<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  <meta name="generator" content="Madoko, version 1.2.3" />
  <meta name="viewport" content="initial-scale=1.0" />
  <meta name="author" content="The P4 Language Consortium" />
  <title>P4 Portable NIC Architecture (PNA)</title>
  <style type="text/css"  class="link">
  /*# sourceURL=madoko.css */
  
  .madoko .toc>.tocblock .tocblock .tocblock {
    margin-left: 2.25em;
  }
  .madoko .toc>.tocblock .tocblock {
    margin-left: 1.5em;
  }
  .madoko .toc-contents>.tocblock>.tocitem {
    font-weight: bold;
  }
  .madoko .toc {
    margin-top: 1em;
  }
  .madoko p.para-continue {
    margin-bottom: 0pt;
  }
  .madoko .para-block+p {
    margin-top: 0pt;
  }
  .madoko ul.para-block, .madoko ol.para-block {
    margin-top: 0pt;
    margin-bottom: 0pt;
  }
  .madoko ul.para-end, .madoko ol.para-end {
    margin-bottom: 1em;
  }
  .madoko dl {
    margin-left: 0em;
  }
  .madoko blockquote {
    font-style: italic;
  }
  .madoko a.localref {
    text-decoration: none;
  }
  .madoko a.localref:hover {
    text-decoration: underline;
  }
  .madoko .footnotes {
    font-size: smaller;
    margin-top: 2em;
  }
  .madoko .footnotes hr {
    width: 50%;
    text-align: left;
  }
  .madoko .footnote {
    margin-left: 1em;
  }
  .madoko .footnote-before {
    margin-left: -1em;
    width: 1em;
    display: inline-block;
  }
  .madoko .align-center, .madoko .align-center>p {
    text-align: center !important;
  }
  .madoko .align-center pre {
    text-align: left;
  }
  .madoko .align-center>* {
    margin-left: auto !important;
    margin-right: auto !important;
  }
  .madoko .align-left, .madoko .align-left>p {
    text-align: left !important;
  }
  .madoko .align-left>* {
    margin-left: 0pt !important;
    margin-right: auto !important;
  }
  .madoko .align-right, .madoko .align-right>p {
    text-align: right !important;
  }
  .madoko .align-right>* {
    margin-left: auto !important;
    margin-right: 0pt !important;
  }
  .madoko .align-center>table,
  .madoko .align-left>table,
  .madoko .align-right>table {
    text-align: left !important;
  }
  .madoko .equation-before {
    float: right;
  }
  .madoko .bibitem {
    font-size: smaller;
  }
  .madoko .bibsearch {
    font-size: x-small;
    text-decoration:none;
    color: black;
    font-family: "Segoe UI Symbol", Symbola, serif;
  }
  .madoko .block, .madoko .figure, .madoko .bibitem, .madoko .equation, .madoko div.math {
    margin-top: 1ex;
    margin-bottom: 1ex;
  }
  .madoko .figure {
    padding: 0.5em;
    margin-left: 0pt;
    margin-right: 0pt;
  }
  .madoko .hidden {
    display: none;
  }
  .madoko .invisible {
    visibility: hidden;
  }
  .madoko.preview .invisible {
    visibility: visible;
    opacity: 0.5;
  }
  .madoko code.code, .madoko span.code {
    white-space: pre-wrap;
  }
  .madoko hr, hr.madoko {
    border: none;
    border-bottom: black solid 1px;
    margin-bottom: 0.5ex;
  }
  .madoko .framed>*:first-child {
    margin-top: 0pt;
  }
  .madoko .framed>*:last-child {
    margin-bottom: 0pt;
  }
  .madoko ul.list-style-type-dash {
      list-style-type: none !important;
  }
  .madoko ul.list-style-type-dash > li:before {
      content: "\2013";
      position: absolute;
      margin-left: -1em;
  }
  .madoko table.madoko {
    border-collapse: collapse;
  }
  .madoko td, .madoko th {
    padding: 0ex 0.5ex;
    margin: 0pt;
    vertical-align: top;
  }
  .madoko .cell-border-left {
    border-left: 1px solid black;
  }
  .madoko .cell-border-right {
    border-right: 1px solid black;
  }
  .madoko thead>tr:first-child>.cell-line,
  .madoko tbody:first-child>tr:first-child>.cell-line {
    border-top: 1px solid black;
    border-bottom: none;
  }
  .madoko .cell-line, .madoko .cell-double-line {
    border-bottom: 1px solid black;
    border-top: none;
  }
  .madoko .cell-double-line {
    border-top: 1px solid black;
    padding-top: 1.5px !important;
  }
  .madoko .input-mathpre .MathJax_Display {
    text-align: left !important;
  }
  .madoko div.input-mathpre {
    text-align: left;
    margin-top: 1.5ex;
    margin-bottom: 1ex;
  }
  .madoko .math-rendering {
    text-align: left;
    white-space: pre;
    color: gray;
  }
  .madoko .mathdisplay {
    text-align: center;
  }
  .madoko span.math-rendering {
    display:inline-block;
    width:8em;
    overflow-x:auto;
    font-size:70%;
  }
  .madoko span.math-rendering::-webkit-scrollbar {
    width:4px;
  }
  .madoko .pretty table {
    border-collapse: collapse;
  }
  .madoko .pretty td {
    padding: 0em;
  }
  .madoko .pretty td.empty {
    min-width: 1.5ex;
  }
  .madoko .pretty td.expander {
    width: 100em;
  }
  body.madoko, .madoko .serif {
    font-family: Cambria,"Times New Roman","Liberation Serif","Times",serif;
  }
  .madoko .sans-serif {
    font-family: "Calibri", "Optima", sans-serif;
  }
  .madoko .symbol {
    font-family: "Segoe UI Symbol", Symbola, serif;
  }
  body.madoko {
    -webkit-text-size-adjust: 100%;       
    text-rendering: optimizeLegibility;
  }
  body.madoko {
    max-width: 88ex; 
    margin: 1em auto;
    padding: 0em 2em;
  }
  body.preview.madoko {
    padding: 0em 1em;
  }
  .madoko p {
    text-align: justify;
  }
  .madoko h1, .madoko h2, .madoko h3, .madoko h4 {
    margin-top: 1.22em;
    margin-bottom: 1ex;
  }
  .madoko h1+p, .madoko h2+p, .madoko h3+p, .madoko h4+p, .madoko h5+p  {
    margin-top: 1ex;
  }
  .madoko h5, .madoko h6 {
    margin-top: 1ex;
    font-size: 1em;
  }
  .madoko h5 {
    margin-bottom: 0.5ex;
  }
  .madoko h5 + p {
    margin-top: 0.5ex;
  }
  .madoko h6 {
    margin-bottom: 0pt;
  }
  .madoko h6 + p {
    margin-top: 0pt;
  }
  .madoko pre, .madoko code, .madoko kbd, .madoko samp, .madoko tt,
  .madoko .monospace, .madoko .token-indent, .madoko .reveal pre, .madoko .reveal code, .madoko .email {
    font-family: Consolas,"Andale Mono WT","Andale Mono",Lucida Console,Monaco,monospace,monospace;
    font-size: 0.85em;
  }
  .madoko pre code, .madoko .token-indent {
    font-size: 0.95em;
  }
  .madoko pre code {
    font-family: inherit !important;
  }
  .madoko ol.linenums li {
    background-color: white;
    list-style-type: decimal;
  }
  .madoko .remote {
    background-color: #F0FFF0;
  }
  .madoko .remote + * {
    margin-top: 0pt;
  }
  @media print {
    body.madoko {
      font-size: 10pt;
    }
    @page {
      margin: 1in 1.5in;
    }
  }
  @media only screen and (max-device-width:1024px) {
    body.madoko {
      padding: 0em 0.5em;
    }
    .madoko li {
      text-align: left;
    }
  }
  
    </style>
  
  </head>
<body class="madoko">

<div class="body madoko" style="font-family:utopia-std, serif;line-adjust:0">
<div class="titleblock align-center para-block" data-line="145" style="text-align:center;line-adjust:0">
<div class="titleheader align-center" data-line="145" style="text-align:center;line-adjust:0">
<div class="title para-block" data-line="145" style="font-size:xx-large;margin-bottom:0.5ex;font-family:helvetica, sans-serif;font-weight:bold;line-adjust:0"><span data-line="145"></span>P4 Portable NIC Architecture (PNA)</div>
<div class="titlenote para-block" data-line="148" style="font-family:helvetica, sans-serif;font-weight:bold;line-adjust:0"><span data-line="148"></span>version 0.5</div></div>
<div class="authors align-center" data-line="153" style="text-align:center;width:80%;font-family:helvetica, sans-serif;font-weight:bold;line-adjust:0"><table class="authorrow columns block" data-line="153" style="margin-top:2ex;width:100%;line-adjust:0">
<tbody><tr><td class="author column" data-line="153" style="text-align:center;line-adjust:0">
<div class="authorname" data-line="153" style="font-size:large;line-adjust:0"><span data-line="153"></span>The P4 Language Consortium</div></td></tr></tbody></table></div>
<div class="titlefooter align-center" data-line="162" style="text-align:center;margin-top:0.5ex;font-family:helvetica, sans-serif;font-weight:bold;line-adjust:0"><span data-line="162"></span>2021-05-18</div></div>
<div class="abstract" data-line="147" style="margin-left:3em;margin-right:3em;font-size:small">
<p class="p noindent" data-line="148"><span data-line="148"></span><strong class="strong-star2">Abstract.</strong><span data-line="148"></span> P4 is a domain-specific language for describing how packets are
processed by a network data plane. A P4 program comprises an
architecture, which describes the structure and capabilities of the
pipeline, and a user program, which specifies the functionality of the
programmable blocks within that pipeline. The Portable NIC
Architecture (PNA) is an architecture that describes the structure and
common capabilities of network interface controller (NIC) devices that
process packets going between one or more interfaces and a host
system.</p></div><span data-line="159"></span>
<nav class="toc toc-contents"><h2 id="sec-contents" class="clearnum h1 heading-contents" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold">Contents</h2>
<div class="tocblock tocblock1">
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-introduction" data-toc-depth="1" data-toc-line="[1]{.heading-label}.&#8194;Introduction" style="toctarget:sec-introduction"><a href="#sec-introduction" class="localref"><span class="heading-label">1</span>.&#8194;Introduction</a></div>
<div class="tocblock tocblock2">
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-packet-processing-in-the-network-to-host-direction" data-toc-depth="2" data-toc-line="[1.1]{.heading-label}.&#8194;Packet processing in the network to host direction" style="toctarget:sec-packet-processing-in-the-network-to-host-direction"><a href="#sec-packet-processing-in-the-network-to-host-direction" class="localref"><span class="heading-label">1.1</span>.&#8194;Packet processing in the network to host direction</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-message-processing" data-toc-depth="2" data-toc-line="[1.2]{.heading-label}.&#8194;Message processing" style="toctarget:sec-message-processing"><a href="#sec-message-processing" class="localref"><span class="heading-label">1.2</span>.&#8194;Message processing</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-packet-processing-in-the-host-to-network-direction" data-toc-depth="2" data-toc-line="[1.3]{.heading-label}.&#8194;Packet processing in the host to network direction" style="toctarget:sec-packet-processing-in-the-host-to-network-direction"><a href="#sec-packet-processing-in-the-host-to-network-direction" class="localref"><span class="heading-label">1.3</span>.&#8194;Packet processing in the host to network direction</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-pna-p416-architecture" data-toc-depth="2" data-toc-line="[1.4]{.heading-label}.&#8194;PNA P4~16~ architecture" style="toctarget:sec-pna-p416-architecture"><a href="#sec-pna-p416-architecture" class="localref"><span class="heading-label">1.4</span>.&#8194;PNA P4<sub>16</sub> architecture</a></div></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-naming-conventions" data-toc-depth="1" data-toc-line="[2]{.heading-label}.&#8194;Naming conventions" style="toctarget:sec-naming-conventions"><a href="#sec-naming-conventions" class="localref"><span class="heading-label">2</span>.&#8194;Naming conventions</a></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="packet-paths" data-toc-depth="1" data-toc-line="[3]{.heading-label}.&#8194;Packet paths" style="toctarget:packet-paths"><a href="#packet-paths" class="localref"><span class="heading-label">3</span>.&#8194;Packet paths</a></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-pna-data-types" data-toc-depth="1" data-toc-line="[4]{.heading-label}.&#8194;PNA Data types" style="toctarget:sec-pna-data-types"><a href="#sec-pna-data-types" class="localref"><span class="heading-label">4</span>.&#8194;PNA Data types</a></div>
<div class="tocblock tocblock2">
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-pna-type-definitions" data-toc-depth="2" data-toc-line="[4.1]{.heading-label}.&#8194;PNA type definitions" style="toctarget:sec-pna-type-definitions"><a href="#sec-pna-type-definitions" class="localref"><span class="heading-label">4.1</span>.&#8194;PNA type definitions</a></div>
<div class="tocblock tocblock3">
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-pna-type-definitions-code" data-toc-depth="3" data-toc-line="[4.1.1]{.heading-label}.&#8194;PNA type definition code excerpt" style="toctarget:sec-pna-type-definitions-code"><a href="#sec-pna-type-definitions-code" class="localref"><span class="heading-label">4.1.1</span>.&#8194;PNA type definition code excerpt</a></div>
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-pna-port-types-and-values" data-toc-depth="3" data-toc-line="[4.1.2]{.heading-label}.&#8194;PNA port types and values" style="toctarget:sec-pna-port-types-and-values"><a href="#sec-pna-port-types-and-values" class="localref"><span class="heading-label">4.1.2</span>.&#8194;PNA port types and values</a></div></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-pna-supported-metadata-types" data-toc-depth="2" data-toc-line="[4.2]{.heading-label}.&#8194;PNA supported metadata types" style="toctarget:sec-pna-supported-metadata-types"><a href="#sec-pna-supported-metadata-types" class="localref"><span class="heading-label">4.2</span>.&#8194;PNA supported metadata types</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-match-kinds" data-toc-depth="2" data-toc-line="[4.3]{.heading-label}.&#8194;Match kinds" style="toctarget:sec-match-kinds"><a href="#sec-match-kinds" class="localref"><span class="heading-label">4.3</span>.&#8194;Match kinds</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-data-plane-vs-control-plane-values" data-toc-depth="2" data-toc-line="[4.4]{.heading-label}.&#8194;Data plane vs. control plane data representations" style="toctarget:sec-data-plane-vs-control-plane-values"><a href="#sec-data-plane-vs-control-plane-values" class="localref"><span class="heading-label">4.4</span>.&#8194;Data plane vs. control plane data representations</a></div></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-programmable-blocks" data-toc-depth="1" data-toc-line="[5]{.heading-label}.&#8194;Programmable blocks" style="toctarget:sec-programmable-blocks"><a href="#sec-programmable-blocks" class="localref"><span class="heading-label">5</span>.&#8194;Programmable blocks</a></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="packet-path-details" data-toc-depth="1" data-toc-line="[6]{.heading-label}.&#8194;Packet Path Details" style="toctarget:packet-path-details"><a href="#packet-path-details" class="localref"><span class="heading-label">6</span>.&#8194;Packet Path Details</a></div>
<div class="tocblock tocblock2">
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-initial-values-of-packets-processed-by-main-parser" data-toc-depth="2" data-toc-line="[6.1]{.heading-label}.&#8194;Initial values of packets processed by main parser" style="toctarget:sec-initial-values-of-packets-processed-by-main-parser"><a href="#sec-initial-values-of-packets-processed-by-main-parser" class="localref"><span class="heading-label">6.1</span>.&#8194;Initial values of packets processed by main parser</a></div>
<div class="tocblock tocblock3">
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-initial-packet-contents-for-packets-from-ports" data-toc-depth="3" data-toc-line="[6.1.1]{.heading-label}.&#8194;Initial packet contents for packets from ports" style="toctarget:sec-initial-packet-contents-for-packets-from-ports"><a href="#sec-initial-packet-contents-for-packets-from-ports" class="localref"><span class="heading-label">6.1.1</span>.&#8194;Initial packet contents for packets from ports</a></div>
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-initial-packet-contents-for-packets-looped-back-from-host-to-network-path" data-toc-depth="3" data-toc-line="[6.1.2]{.heading-label}.&#8194;Initial packet contents for packets looped back from host-to-network path" style="toctarget:sec-initial-packet-contents-for-packets-looped-back-from-host-to-network-path"><a href="#sec-initial-packet-contents-for-packets-looped-back-from-host-to-network-path" class="localref"><span class="heading-label">6.1.2</span>.&#8194;Initial packet contents for packets looped back from host-to-network path</a></div></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-behavior-of-packets-after-pre-block-is-complete" data-toc-depth="2" data-toc-line="[6.2]{.heading-label}.&#8194;Behavior of packets after pre block is complete" style="toctarget:sec-behavior-of-packets-after-pre-block-is-complete"><a href="#sec-behavior-of-packets-after-pre-block-is-complete" class="localref"><span class="heading-label">6.2</span>.&#8194;Behavior of packets after pre block is complete</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-initial-values-of-packets-processed-in-network-to-host-direction-by-main-block" data-toc-depth="2" data-toc-line="[6.3]{.heading-label}.&#8194;Initial values of packets processed in network-to-host direction by main block" style="toctarget:sec-initial-values-of-packets-processed-in-network-to-host-direction-by-main-block"><a href="#sec-initial-values-of-packets-processed-in-network-to-host-direction-by-main-block" class="localref"><span class="heading-label">6.3</span>.&#8194;Initial values of packets processed in network-to-host direction by main block</a></div>
<div class="tocblock tocblock3">
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-initial-packet-contents-for-normal-packets" data-toc-depth="3" data-toc-line="[6.3.1]{.heading-label}.&#8194;Initial packet contents for normal packets" style="toctarget:sec-initial-packet-contents-for-normal-packets"><a href="#sec-initial-packet-contents-for-normal-packets" class="localref"><span class="heading-label">6.3.1</span>.&#8194;Initial packet contents for normal packets</a></div>
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-initial-packet-contents-for-recirculated-packets" data-toc-depth="3" data-toc-line="[6.3.2]{.heading-label}.&#8194;Initial packet contents for recirculated packets" style="toctarget:sec-initial-packet-contents-for-recirculated-packets"><a href="#sec-initial-packet-contents-for-recirculated-packets" class="localref"><span class="heading-label">6.3.2</span>.&#8194;Initial packet contents for recirculated packets</a></div></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-behavior-of-packets-after-main-block-is-complete-in-network-to-host-direction" data-toc-depth="2" data-toc-line="[6.4]{.heading-label}.&#8194;Behavior of packets after main block is complete in network-to-host direction" style="toctarget:sec-behavior-of-packets-after-main-block-is-complete-in-network-to-host-direction"><a href="#sec-behavior-of-packets-after-main-block-is-complete-in-network-to-host-direction" class="localref"><span class="heading-label">6.4</span>.&#8194;Behavior of packets after main block is complete in network-to-host direction</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-initial-values-of-packets-processed-in-host-to-network-direction-by-main-block" data-toc-depth="2" data-toc-line="[6.5]{.heading-label}.&#8194;Initial values of packets processed in host-to-network direction by main block" style="toctarget:sec-initial-values-of-packets-processed-in-host-to-network-direction-by-main-block"><a href="#sec-initial-values-of-packets-processed-in-host-to-network-direction-by-main-block" class="localref"><span class="heading-label">6.5</span>.&#8194;Initial values of packets processed in host-to-network direction by main block</a></div>
<div class="tocblock tocblock3">
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-initial-packet-contents-for-normal-packets" data-toc-depth="3" data-toc-line="[6.5.1]{.heading-label}.&#8194;Initial packet contents for normal packets" style="toctarget:sec-initial-packet-contents-for-normal-packets"><a href="#sec-initial-packet-contents-for-normal-packets" class="localref"><span class="heading-label">6.5.1</span>.&#8194;Initial packet contents for normal packets</a></div>
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-initial-packet-contents-for-recirculated-packets" data-toc-depth="3" data-toc-line="[6.5.2]{.heading-label}.&#8194;Initial packet contents for recirculated packets" style="toctarget:sec-initial-packet-contents-for-recirculated-packets"><a href="#sec-initial-packet-contents-for-recirculated-packets" class="localref"><span class="heading-label">6.5.2</span>.&#8194;Initial packet contents for recirculated packets</a></div>
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-initial-packet-contents-for-packets-looped-back-after-network-to-host-main-processing" data-toc-depth="3" data-toc-line="[6.5.3]{.heading-label}.&#8194;Initial packet contents for packets looped back after network-to-host main processing" style="toctarget:sec-initial-packet-contents-for-packets-looped-back-after-network-to-host-main-processing"><a href="#sec-initial-packet-contents-for-packets-looped-back-after-network-to-host-main-processing" class="localref"><span class="heading-label">6.5.3</span>.&#8194;Initial packet contents for packets looped back after network-to-host main processing</a></div></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-behavior-of-packets-after-main-block-is-complete-in-host-to-network-direction" data-toc-depth="2" data-toc-line="[6.6]{.heading-label}.&#8194;Behavior of packets after main block is complete in host-to-network direction" style="toctarget:sec-behavior-of-packets-after-main-block-is-complete-in-host-to-network-direction"><a href="#sec-behavior-of-packets-after-main-block-is-complete-in-host-to-network-direction" class="localref"><span class="heading-label">6.6</span>.&#8194;Behavior of packets after main block is complete in host-to-network direction</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-contents-of-packets-sent-out-to-ports" data-toc-depth="2" data-toc-line="[6.7]{.heading-label}.&#8194;Contents of packets sent out to ports" style="toctarget:sec-contents-of-packets-sent-out-to-ports"><a href="#sec-contents-of-packets-sent-out-to-ports" class="localref"><span class="heading-label">6.7</span>.&#8194;Contents of packets sent out to ports</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-functions-for-directing-packets" data-toc-depth="2" data-toc-line="[6.8]{.heading-label}.&#8194;Functions for directing packets" style="toctarget:sec-functions-for-directing-packets"><a href="#sec-functions-for-directing-packets" class="localref"><span class="heading-label">6.8</span>.&#8194;Functions for directing packets</a></div>
<div class="tocblock tocblock3">
<div class="tocitem tocitem3" data-toc-target-elem="h3" data-toc-target="sec-extern-function-send_to_port" data-toc-depth="3" data-toc-line="[6.8.1]{.heading-label}.&#8194;Extern function `send_to_port`" style="toctarget:sec-extern-function-send_to_port"><a href="#sec-extern-function-send_to_port" class="localref"><span class="heading-label">6.8.1</span>.&#8194;Extern function <code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port</code></a></div></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-packet-mirroring" data-toc-depth="2" data-toc-line="[6.9]{.heading-label}.&#8194;Packet Mirroring" style="toctarget:sec-packet-mirroring"><a href="#sec-packet-mirroring" class="localref"><span class="heading-label">6.9</span>.&#8194;Packet Mirroring</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-packet-recirculation" data-toc-depth="2" data-toc-line="[6.10]{.heading-label}.&#8194;Packet recirculation" style="toctarget:sec-packet-recirculation"><a href="#sec-packet-recirculation" class="localref"><span class="heading-label">6.10</span>.&#8194;Packet recirculation</a></div></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-pna-extern-objects" data-toc-depth="1" data-toc-line="[7]{.heading-label}.&#8194;PNA Extern Objects" style="toctarget:sec-pna-extern-objects"><a href="#sec-pna-extern-objects" class="localref"><span class="heading-label">7</span>.&#8194;PNA Extern Objects</a></div>
<div class="tocblock tocblock2">
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-extern-restrictions" data-toc-depth="2" data-toc-line="[7.1]{.heading-label}.&#8194;Restrictions on where externs may be used" style="toctarget:sec-extern-restrictions"><a href="#sec-extern-restrictions" class="localref"><span class="heading-label">7.1</span>.&#8194;Restrictions on where externs may be used</a></div></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-pna-table-properties" data-toc-depth="1" data-toc-line="[8]{.heading-label}.&#8194;PNA Table Properties" style="toctarget:sec-pna-table-properties"><a href="#sec-pna-table-properties" class="localref"><span class="heading-label">8</span>.&#8194;PNA Table Properties</a></div>
<div class="tocblock tocblock2">
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-add-on-miss" data-toc-depth="2" data-toc-line="[8.1]{.heading-label}.&#8194;Tables with add-on-miss capability" style="toctarget:sec-add-on-miss"><a href="#sec-add-on-miss" class="localref"><span class="heading-label">8.1</span>.&#8194;Tables with add-on-miss capability</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-idle-timeout" data-toc-depth="2" data-toc-line="[8.2]{.heading-label}.&#8194;Table entry timeout notification" style="toctarget:sec-idle-timeout"><a href="#sec-idle-timeout" class="localref"><span class="heading-label">8.2</span>.&#8194;Table entry timeout notification</a></div></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-timestamps" data-toc-depth="1" data-toc-line="[9]{.heading-label}.&#8194;Timestamps" style="toctarget:sec-timestamps"><a href="#sec-timestamps" class="localref"><span class="heading-label">9</span>.&#8194;Timestamps</a></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-atomicity-of-control-plane-api-operations" data-toc-depth="1" data-toc-line="[10]{.heading-label}.&#8194;Atomicity of control plane API operations" style="toctarget:sec-atomicity-of-control-plane-api-operations"><a href="#sec-atomicity-of-control-plane-api-operations" class="localref"><span class="heading-label">10</span>.&#8194;Atomicity of control plane API operations</a></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="sec-appendix--open-issues" data-toc-depth="1" data-toc-line="[A]{.heading-label}.&#8194;Appendix: Open Issues" style="toctarget:sec-appendix--open-issues"><a href="#sec-appendix--open-issues" class="localref"><span class="heading-label">A</span>.&#8194;Appendix: Open Issues</a></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="appendix-rationale" data-toc-depth="1" data-toc-line="[B]{.heading-label}.&#8194;Appendix: Rationale for design" style="toctarget:appendix-rationale"><a href="#appendix-rationale" class="localref"><span class="heading-label">B</span>.&#8194;Appendix: Rationale for design</a></div>
<div class="tocblock tocblock2">
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-why-a-common-pipeline-instead-of-separate-pipelines-for-each-direction" data-toc-depth="2" data-toc-line="[B.1]{.heading-label}.&#8194;Why a common pipeline, instead of separate pipelines for each direction?" style="toctarget:sec-why-a-common-pipeline-instead-of-separate-pipelines-for-each-direction"><a href="#sec-why-a-common-pipeline-instead-of-separate-pipelines-for-each-direction" class="localref"><span class="heading-label">B.1</span>.&#8194;Why a common pipeline, instead of separate pipelines for each direction?</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-why-separate-programmable-pre-blocks-for-pre-decryption-packet-processing" data-toc-depth="2" data-toc-line="[B.2]{.heading-label}.&#8194;Why separate programmable pre blocks for pre-decryption packet processing?" style="toctarget:sec-why-separate-programmable-pre-blocks-for-pre-decryption-packet-processing"><a href="#sec-why-separate-programmable-pre-blocks-for-pre-decryption-packet-processing" class="localref"><span class="heading-label">B.2</span>.&#8194;Why separate programmable pre blocks for pre-decryption packet processing?</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="appendix-reparsing" data-toc-depth="2" data-toc-line="[B.3]{.heading-label}.&#8194;Is it inefficient to have the `MainParser` redo work?" style="toctarget:appendix-reparsing"><a href="#appendix-reparsing" class="localref"><span class="heading-label">B.3</span>.&#8194;Is it inefficient to have the <code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainParser</code> redo work?</a></div></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="appendix-packet-path-figures" data-toc-depth="1" data-toc-line="[C]{.heading-label}.&#8194;Appendix: Packet path figures" style="toctarget:appendix-packet-path-figures"><a href="#appendix-packet-path-figures" class="localref"><span class="heading-label">C</span>.&#8194;Appendix: Packet path figures</a></div>
<div class="tocblock tocblock2">
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-network-to-host" data-toc-depth="2" data-toc-line="[C.1]{.heading-label}.&#8194;Network to host" style="toctarget:sec-network-to-host"><a href="#sec-network-to-host" class="localref"><span class="heading-label">C.1</span>.&#8194;Network to host</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-network-to-host-with-mirror-copy-to-different-host" data-toc-depth="2" data-toc-line="[C.2]{.heading-label}.&#8194;Network to host with mirror copy to different host" style="toctarget:sec-network-to-host-with-mirror-copy-to-different-host"><a href="#sec-network-to-host-with-mirror-copy-to-different-host" class="localref"><span class="heading-label">C.2</span>.&#8194;Network to host with mirror copy to different host</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-host-to-network" data-toc-depth="2" data-toc-line="[C.3]{.heading-label}.&#8194;Host to network" style="toctarget:sec-host-to-network"><a href="#sec-host-to-network" class="localref"><span class="heading-label">C.3</span>.&#8194;Host to network</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-host-to-network-with-mirror-copy-to-a-different-host" data-toc-depth="2" data-toc-line="[C.4]{.heading-label}.&#8194;Host to network with mirror copy to a different host" style="toctarget:sec-host-to-network-with-mirror-copy-to-a-different-host"><a href="#sec-host-to-network-with-mirror-copy-to-a-different-host" class="localref"><span class="heading-label">C.4</span>.&#8194;Host to network with mirror copy to a different host</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-host-to-host" data-toc-depth="2" data-toc-line="[C.5]{.heading-label}.&#8194;Host to host" style="toctarget:sec-host-to-host"><a href="#sec-host-to-host" class="localref"><span class="heading-label">C.5</span>.&#8194;Host to host</a></div>
<div class="tocitem tocitem2" data-toc-target-elem="h2" data-toc-target="sec-port-to-port" data-toc-depth="2" data-toc-line="[C.6]{.heading-label}.&#8194;Port to port" style="toctarget:sec-port-to-port"><a href="#sec-port-to-port" class="localref"><span class="heading-label">C.6</span>.&#8194;Port to port</a></div></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="appendix-packet-ordering" data-toc-depth="1" data-toc-line="[D]{.heading-label}.&#8194;Appendix: Packet ordering" style="toctarget:appendix-packet-ordering"><a href="#appendix-packet-ordering" class="localref"><span class="heading-label">D</span>.&#8194;Appendix: Packet ordering</a></div>
<div class="tocitem tocitem1" data-toc-target-elem="h1" data-toc-target="appendix-revision-history" data-toc-depth="1" data-toc-line="[E]{.heading-label}.&#8194;Appendix: Revision History" style="toctarget:appendix-revision-history"><a href="#appendix-revision-history" class="localref"><span class="heading-label">E</span>.&#8194;Appendix: Revision History</a></div></div></nav><h2 id="sec-introduction" class="h1" data-line="161" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="161"></span><span class="heading-before"><span class="heading-label">1</span>.&#8194;</span><span data-line="161"></span>Introduction</h2>
<p class="p noindent" data-line="163"><span data-line="163"></span>Note that this document is still a working draft.  Significant changes
are expected to be made before version 1.0 of this specification is
released.
</p>
<p class="p indent" data-line="167"><span data-line="167"></span>The Portable NIC Architecture (PNA) is P4 architecture that defines
the structure and common capabilities for network interface controller
(NIC) devices. PNA comprises two main components:
</p>
<ol class="ol loose" data-line="171">
<li class="li ol-li loose-li" data-line="171">
<p data-line="171"><span data-line="171"></span>A programmable pipeline that can be used to realize a variety of
different <span data-line="172"></span>&#8220;packet paths&#8221;<span data-line="172"></span> going between the various ports on the device
(e.g., network interfaces or the host system it is attached to), and
</p></li>
<li class="li ol-li loose-li" data-line="175">
<p data-line="175"><span data-line="175"></span>A library of types (e.g., intrinsict and standard metadata) and
P4<span data-line="176"></span><sub>16</sub><span data-line="176"></span> externs (e.g., counters, meters, and registers).
</p></li></ol>

<p class="p noindent" data-line="178"><span data-line="178"></span>PNA is designed to model the common features of a broad class of NIC
devices. By providing standard APIs and coding guidelines, the hope is
to enable developers to write programs that are portable across
multiple NIC devices that are conformant to the PNA<span data-line="181"></span><sup id="back-fn-pnaportability" ><a href="#fn-pnaportability" title="1.Of course, given the tight hardware resource
constraints on NIC devices, there is no promise that a given P4
program that compiles on one device will also compile on another
device. However, it should at least be the case that those P4
programs that are able to compile on multiple NIC devices should
process packets as described in this document.
&#8617;" class="footnote-ref localref" ><span class="footnote-label">1</span></a></sup><span data-line="181"></span>.
</p>
<p class="p indent" data-line="190"><span data-line="190"></span>The Portable NIC Architecture (PNA) Model has four programmable P4
blocks and several fixed-function blocks, as shown in Figure
<span data-line="192"></span><a href="#fig-nic" title="Programmable NIC Architecture Block Diagram" class="localref" style="target-element:figure"><span class="figure-label">1</span></a><span data-line="192"></span>. The behavior of the programmable blocks is specified using
P4. The network ports, packet queues, and (optional) inline extern
blocks are fixed-function blocks that can be configured by the control
plane, but are not intended to be programmed using P4.
</p>
<figure id="fig-nic" class="figure floating align-center float" data-line="197" style="text-align:center;float-env:figure;float-name:Figure;page-align:here">
<p class="p noindent" data-line="198"><span data-line="198"></span><img src="" alt="nic" data-path="figs/pna-block-diagram.png" data-linkid="nic" style="width:100%"><span data-line="198"></span>
</p>
<hr  class="figureline madoko" data-line="199" style="display:block">

<div class="p noindent" data-line="200"><span data-line="200"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">1</span>.</strong>&#160;</span><span class="caption-text">Programmable NIC Architecture Block Diagram</span></fig-caption></div></figure><h3 id="sec-packet-processing-in-the-network-to-host-direction" class="h2" data-line="202" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="202"></span><span class="heading-before"><span class="heading-label">1.1</span>.&#8194;</span><span data-line="202"></span>Packet processing in the network to host direction</h3>
<p class="p noindent" data-line="204"><span data-line="204"></span>Packets arriving from a network port first go through a <span data-line="204"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainParser</code><span data-line="204"></span>
and a <span data-line="205"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PreControl</code><span data-line="205"></span>. The <span data-line="205"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PreControl</code><span data-line="205"></span> can optionally perform
table lookups. Its purpose is to determine whether a packet requires
processing by the net-to-host inline extern block.
</p>
<p class="p indent" data-line="209"><span data-line="209"></span>For example, the net-to-host inline extern block may perform
decryption of packet payloads according to the IPsec protocol. In this
case, the main parser and pre control would be programmed to identify
whether the packet was encrypted using IPsec, and if so, what security
association it belongs to. For instance, the <span data-line="213"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PreControl</code><span data-line="213"></span> code might
drop the packet if the packet had an IPsec header, but one or more P4
table lookups determined that the packet does not belong to any
security association that had been established by the control plane
software. Note that the net-to-host inline extern block may modify the
entire payload of the received packet<span data-line="218"></span>&#8212;<span data-line="218"></span>e.g., decrypting the encrypted
portion of the payload. Hence, the resulting packet might contain not
only the original headers that were parsed by the first invocation of
the <span data-line="221"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainParser</code><span data-line="221"></span>, but also headers that could not have been parsed as
they were previously encrypted. See section<span data-line="222"></span>&nbsp;<a href="#appendix-reparsing" title="B.3.&#8194;Is it inefficient to have the MainParser redo work?" class="localref" style="target-element:h2"><span class="heading-label">B.3</span></a><span data-line="222"></span> for
additional details.
</p>
<p class="p indent" data-line="225"><span data-line="225"></span>After decryption, the <span data-line="225"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainParser</code><span data-line="225"></span> can perform the full parsing
required for implementing the desired data plane functionality.
</p>
<p class="p indent" data-line="228"><span data-line="228"></span>The <span data-line="228"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="228"></span> is typically where the bulk of code would be written
for processing packets. It transforms headers, updates stateful
elements like counters, meters, and registers, and optionally
associates additional user-defined metadata with the packet. The
<span data-line="232"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainDeparser</code><span data-line="232"></span> serializes the headers back into a packet that can be
sent onwards.
</p>
<p class="p indent" data-line="235"><span data-line="235"></span>After the <span data-line="235"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainDeparser</code><span data-line="235"></span>, the packet may either:
<span data-line="236"></span><em class="em-star1"> proceed to the message processing part of the NIC, and then typically on
  to the host system, or
</em><span data-line="238"></span> turn around and head back towards the network ports. This enables
  on-NIC processing of port-to-port packets without ever traversing the host system.
</p>
<p class="p indent" data-line="241"><span data-line="241"></span>Figure<span data-line="241"></span>&nbsp;<a href="#fig-nic" title="Programmable NIC Architecture Block Diagram" class="localref" style="target-element:figure"><span class="figure-label">1</span></a><span data-line="241"></span> shows multiple hosts. Some NICs support PCI Express
connections to multiple host CPU complexes. It is also common for NICs
to have an array of one or more CPU cores inside of the NIC device
itself, and these can be the target for packets received from the
network, and/or the source of packets sent to the network, just as the
other hosts can be. For the purposes of the PNA, such CPU cores are
considered as another host.
</p><h3 id="sec-message-processing" class="h2" data-line="249" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="249"></span><span class="heading-before"><span class="heading-label">1.2</span>.&#8194;</span><span data-line="249"></span>Message processing</h3>
<p class="p noindent" data-line="251"><span data-line="251"></span>The focus in the current version of this specification is on the four
P4-programmable blocks mentioned above. The details of how one can
use P4 to program the message processing portion of a NIC is left as
a future extension of this specification. While there are options for
exactly what packet processing functions can be performed in the four
primary blocks described above, versus the message processing block, the
division is expected to be:
</p>
<ul class="ul list-dash compact" data-line="259">
<li class="li ul-li list-dash-li compact-li" data-line="259"><span data-line="259"></span>The primary programmable blocks deal solely with individual network
packets, which are at most one network maximum transmission unit
(MTU) in size.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="262"><span data-line="262"></span>The message processing block is responsible for converting between
large messages in host memory and network size packets on the
network, and for dealing with one or more host operating systems,
drivers, and/or message descriptor formats in host memory.
</li></ul>

<p class="p noindent" data-line="267"><span data-line="267"></span>For example, in its role of converting between large messages and
network packets in the host-to-network direction, message processing
would implement features like large send offload (LSO), TCP
segmentation offload (TSO), and Remote Direct Memory Access (RDMA)
over Converged Ethernet (RoCE). In the network-to-host direction it
would assist in such features as large receive offload (LRO) and RoCE.
</p>
<p class="p indent" data-line="274"><span data-line="274"></span>In its role of handling different kinds of operating systems, drivers,
and message descriptor formats, the message processing block may deal
with one or more of the following standards:
- VirtIO
- SR-IOV
</p>
<p class="p indent" data-line="280"><span data-line="280"></span>Another potential criteria for dividing packet processing
functionality between message processing and the rest of the NIC is
for division of control plane responsibilities. For example, in some
network deployments the NIC message processing block configuration is
tightly coupled with the host operating system, whereas the
<span data-line="285"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="285"></span> is controlled by network-focused control plane software.
</p><h3 id="sec-packet-processing-in-the-host-to-network-direction" class="h2" data-line="287" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="287"></span><span class="heading-before"><span class="heading-label">1.3</span>.&#8194;</span><span data-line="287"></span>Packet processing in the host to network direction</h3>
<p class="p noindent" data-line="289"><span data-line="289"></span>Messages originating in one of the hosts are segmented into network
MTU size packets (if the host has not already done so) in the message
processing block, and are then sent to the main block for further
processing.
</p>
<p class="p indent" data-line="294"><span data-line="294"></span>The same <span data-line="294"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainParser</code><span data-line="294"></span>, <span data-line="294"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PreControl</code><span data-line="294"></span>, <span data-line="294"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="294"></span>, and <span data-line="294"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainDeparser</code><span data-line="294"></span>
that process packets from the network are also used to process packets
from the host. PNA was designed this way for two reasons:
</p>
<ul class="ul list-dash compact" data-line="298">
<li class="li ul-li list-dash-li compact-li" data-line="298"><span data-line="298"></span>It is expected that in many cases, the packet processing in both
directions will have many similarities between them. Writing common
P4 code for both eliminates code duplication that would occur if the
code for each direction was written separately.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="302"><span data-line="302"></span>Having a single <span data-line="302"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="302"></span> in the P4 language enables tables and
externs such as counters and registers to be instantiated once, and
shared by packets being processed in both directions. The hardware
of many NICs supports this design, without having to instantiate a
physically separate table for each direction. Especially for large
tables used by packet processing in both directions, this approach can
significantly reduce the memory required. It is also critical for
some stateful features (e.g. those using the table add-on-miss
capability) to access the same table in memory when processing
packets in either direction.
</li></ul>

<p class="p noindent" data-line="317"><span data-line="317"></span>After finishing processing in the <span data-line="317"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="317"></span>, the packet may be
enqueued in one of several queues (the number of such queues is target
specific). After queueing there may be a host-to-net inline extern.
For example, the host-to-net inline extern block may perform
encryption of packet payloads according to the IPsec protocol. In this
case, the <span data-line="322"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="322"></span> would indicate that this processing should be
form via assigning appropriate values to standard metadata fields
created for this purpose.
</p>
<p class="p indent" data-line="326"><span data-line="326"></span>Next, the two primary choices for the next place the packet will go are:
</p>
<ul class="ul list-dash compact" data-line="328">
<li class="li ul-li list-dash-li compact-li" data-line="328"><span data-line="328"></span>proceed to be emitted out of one of the network ports, or 
</li>
<li class="li ul-li list-dash-li compact-li" data-line="329"><span data-line="329"></span>turn around and head back towards the host system, which enables
on-NIC processing of VM-to-VM or host-to-host packets (i.e., on a
system with multiple hosts).
</li></ul>

<p class="p noindent" data-line="333"><span data-line="333"></span>The choices of which queue to use, what kind of processing to perform
in the host-to-net inline extern, which network port to go to, or
whether to loop back, are all controlled from the P4 code running in
the <span data-line="336"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="336"></span> block, via extern functions defined by this PNA
specification.
</p>
<p class="p indent" data-line="343"><span data-line="343"></span>Note that packets processed in the main block cannot <span data-line="343"></span>&#8220;change
direction&#8221;<span data-line="344"></span> internally. That is, packets from the network must go out
the to-host path, and packets from the host must go out the to-net
path. There are loopback paths outside of the main block as shown in
Figure<span data-line="347"></span>&nbsp;<a href="#fig-nic" title="Programmable NIC Architecture Block Diagram" class="localref" style="target-element:figure"><span class="figure-label">1</span></a><span data-line="347"></span>.
</p><h3 id="sec-pna-p416-architecture" class="h2" data-line="349" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="349"></span><span class="heading-before"><span class="heading-label">1.4</span>.&#8194;</span><span data-line="349"></span>PNA P4<span data-line="349"></span><sub>16</sub><span data-line="349"></span> architecture</h3>
<p class="p noindent" data-line="351"><span data-line="351"></span>A programmer targeting the PNA is required to provide P4 definitions
for each of the programmable blocks in the pipeline (see section
<span data-line="353"></span><a href="#sec-programmable-blocks" title="5.&#8194;Programmable blocks" class="localref" style="target-element:h1"><span class="heading-label">5</span></a><span data-line="353"></span>). The programmable block inputs and outputs
are parameterized on the types of user defined headers and metadata.
The top-level PNA program instantiates a package named <span data-line="355"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">main</code><span data-line="355"></span> with the
programmable blocks passed as arguments (see Section TBD for an
example). Note that the <span data-line="357"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">main</code><span data-line="357"></span> package is not to be confused with the
<span data-line="358"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="358"></span>.
</p>
<p class="p indent" data-line="364"><span data-line="364"></span>A P4 programmer wishing to maximize the portability of their program
should follow several general guidelines:
</p>
<ul class="ul list-dash compact" data-line="367">
<li class="li ul-li list-dash-li compact-li" data-line="367"><span data-line="367"></span>Do not use undefined values in a way that affects the resulting
output packet(s), or for side effects such as updating <span data-line="368"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Counter</code><span data-line="368"></span>,
<span data-line="369"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Meter</code><span data-line="369"></span> or <span data-line="369"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Register</code><span data-line="369"></span> instances.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="370"><span data-line="370"></span>Use as few resources as possible, e.g. table search key bits, array
sizes, quantity of metadata associated with packets, etc.
</li></ul>

<p class="p noindent" data-line="373"><span data-line="373"></span>This document contains excerpts of several P4<span data-line="373"></span><sub>16</sub><span data-line="373"></span> programs that use
the <span data-line="374"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna.p4</code><span data-line="374"></span> include file and demonstrate features of PNA. Source code
for the complete programs can be found in the official repository
containing the PNA specification<span data-line="376"></span><sup id="back-fn-pnaexampleprograms" ><a href="#fn-pnaexampleprograms" title="2.https://&#8203;github.&#8203;com/&#8203;p4lang/&#8203;pna
in directory examples.  Direct link:
https://&#8203;github.&#8203;com/&#8203;p4lang/&#8203;pna/&#8203;tree/&#8203;master/&#8203;examples
&#8617;" class="footnote-ref localref" ><span class="footnote-label">2</span></a></sup><span data-line="376"></span>.
</p><h2 id="sec-naming-conventions" class="h1" data-line="382" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="382"></span><span class="heading-before"><span class="heading-label">2</span>.&#8194;</span><span data-line="382"></span>Naming conventions</h2>
<p class="p noindent" data-line="384"><span data-line="384"></span>In this document we use the following naming conventions:
</p>
<ul class="ul list-dash compact" data-line="386">
<li class="li ul-li list-dash-li compact-li" data-line="386"><span data-line="386"></span>Types are named using CamelCase followed by <span data-line="386"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">_t</code><span data-line="386"></span>. For example, <span data-line="386"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PortId_t</code><span data-line="386"></span>.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="387"><span data-line="387"></span>Control types and extern object types are named using CamelCase. For
example <span data-line="388"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">IngressParser</code><span data-line="388"></span>.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="389"><span data-line="389"></span>Struct types are named using lower case words separated by <span data-line="389"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">_</code><span data-line="389"></span>
followed by <span data-line="390"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">_t</code><span data-line="390"></span>. For example <span data-line="390"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_ingress_input_metadata_t</code><span data-line="390"></span>.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="391"><span data-line="391"></span>Actions, extern methods, extern functions, headers, structs, and
instances of controls and externs start with lower case and words
are separated using <span data-line="393"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">_</code><span data-line="393"></span>. For example <span data-line="393"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port</code><span data-line="393"></span>.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="394"><span data-line="394"></span>Enum members, const definitions, and <span data-line="394"></span>#<span data-line="394"></span>define constants are all
caps, with words separated by <span data-line="395"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">_</code><span data-line="395"></span>. For example <span data-line="395"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PNA_PORT_CPU</code><span data-line="395"></span>.
</li></ul>

<p class="p noindent" data-line="397"><span data-line="397"></span>Architecture specific metadata (e.g. structs) are prefixed by <span data-line="397"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_</code><span data-line="397"></span>.
</p><h2 id="packet-paths" class="h1" data-line="399" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="399"></span><span class="heading-before"><span class="heading-label">3</span>.&#8194;</span><span data-line="399"></span>Packet paths</h2>
<p class="p noindent" data-line="401"><span data-line="401"></span>Figure<span data-line="401"></span>&nbsp;<a href="#fig-packet-paths" title="Packet Paths in PNA" class="localref" style="target-element:figure"><span class="figure-label">2</span></a><span data-line="401"></span> shows all possible paths for packets that
must be supported by a PNA implementation. An implementation is
allowed to support paths for packets that are not described here.
</p>
<div class="tbd" data-line="405" style="color:red">
<div class="tbdblock" data-line="406">
<p class="p noindent" data-line="407"><span data-line="407"></span>TBD: Create another figure with names for the paths.</p></div></div>
<figure id="fig-packet-paths" class="figure floating align-center float" data-line="409" style="text-align:center;float-env:figure;float-name:Figure;page-align:here">
<p class="p noindent" data-line="410"><span data-line="410"></span><img src="" alt="packet-paths" data-path="figs/pna-packet-paths-figure.png" data-linkid="packet-paths" style="width:100%"><span data-line="410"></span>
</p>
<hr  class="figureline madoko" data-line="411" style="display:block">

<div class="p noindent" data-line="412"><span data-line="412"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">2</span>.</strong>&#160;</span><span class="caption-text">Packet Paths in PNA</span></fig-caption></div></figure>
<p class="p noindent" data-line="414"><span data-line="414"></span>Table<span data-line="414"></span>&nbsp;<a href="#results-of-one-pkt-thru-main" title="Result of packet processed one time by main." class="localref" style="target-element:tablefigure"><span class="table-label">1</span></a><span data-line="414"></span> shows what can happen to a
packet as a result of a single time being processed through the four
programmable blocks of the packet processing part of PNA, referred to
here as <span data-line="417"></span>&#8220;main&#8221;<span data-line="417"></span>.
</p>
<figure id="results-of-one-pkt-thru-main" class="tablefigure floating align-center float" data-line="419" style="text-align:center;float-env:table;float-name:Table"><table class="madoko block" data-line="420">
<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-line="420" data-row="0" data-col="1" style="text-align:left"></th><th class="thead tr-even col cell-border-left cell-line col-even" data-line="420" data-row="0" data-col="2" style="text-align:left"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-line="420" data-row="0" data-col="3" style="text-align:left"></th></tr>
<tr><th class="col cell-border-left thead tr-odd tr-first col-odd col-first" data-line="421" data-row="1" data-col="1" style="font-weight:bold;text-align:left"><span data-line="421"></span>             </th><th class="col cell-border-left thead tr-odd tr-first col-even" data-line="421" data-row="1" data-col="2" style="font-weight:bold;text-align:left"><span data-line="421"></span> Processed     </th><th class="col cell-border-left cell-border-right thead tr-odd tr-first col-odd col-last" data-line="421" data-row="1" data-col="3" style="font-weight:bold;text-align:left"><span data-line="421"></span> Resulting          </th></tr>
<tr><th class="col cell-border-left thead tr-even tr-last col-odd col-first" data-line="422" data-row="2" data-col="1" style="font-weight:bold;text-align:left"><span data-line="422"></span> Description </th><th class="col cell-border-left thead tr-even tr-last col-even" data-line="422" data-row="2" data-col="2" style="font-weight:bold;text-align:left"><span data-line="422"></span> next by       </th><th class="col cell-border-left cell-border-right thead tr-even tr-last col-odd col-last" data-line="422" data-row="2" data-col="3" style="font-weight:bold;text-align:left"><span data-line="422"></span> packet(s)          </th></tr></thead>
<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-row="0" data-col="2" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-row="0" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-line="424" data-row="1" data-col="1" style="text-align:left"><span data-line="424"></span> packet from   </td><td class="tbody tr-odd tr-first col cell-border-left col-even" data-line="424" data-row="1" data-col="2" style="text-align:left"><span data-line="424"></span> main, with    </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-odd col-last" data-line="424" data-row="1" data-col="3" style="text-align:left"><span data-line="424"></span> Zero or more mirrored  </td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="425" data-row="2" data-col="1" style="text-align:left"><span data-line="425"></span> network port  </td><td class="tbody tr-even col cell-border-left col-even" data-line="425" data-row="2" data-col="2" style="text-align:left"><span data-line="425"></span> direction     </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="425" data-row="2" data-col="3" style="text-align:left"><span data-line="425"></span> packets, plus at most  </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="426" data-row="2" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left col-even" data-line="426" data-row="2" data-col="2" style="text-align:left"><span data-line="426"></span>               </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="426" data-row="2" data-col="3" style="text-align:left"><span data-line="426"></span> </td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="427" data-row="3" data-col="1" style="text-align:left"><span data-line="427"></span> packet from   </td><td class="tbody tr-odd col cell-border-left col-even" data-line="427" data-row="3" data-col="2" style="text-align:left"><span data-line="427"></span> <span data-line="427"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NET_TO_HOST</code><span data-line="427"></span> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="427" data-row="3" data-col="3" style="text-align:left"><span data-line="427"></span> one of: a net-to-host  </td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="428" data-row="4" data-col="1" style="text-align:left"><span data-line="428"></span> net-to-host   </td><td class="tbody tr-even col cell-border-left col-even" data-line="428" data-row="4" data-col="2" style="text-align:left"><span data-line="428"></span>               </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="428" data-row="4" data-col="3" style="text-align:left"><span data-line="428"></span> recirculated packet,   </td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="429" data-row="5" data-col="1" style="text-align:left"><span data-line="429"></span> recirculate   </td><td class="tbody tr-odd col cell-border-left col-even" data-line="429" data-row="5" data-col="2" style="text-align:left"><span data-line="429"></span>               </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="429" data-row="5" data-col="3" style="text-align:left"><span data-line="429"></span> or one to-host packet. </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="430" data-row="5" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left col-even" data-line="430" data-row="5" data-col="2" style="text-align:left"><span data-line="430"></span>               </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="430" data-row="5" data-col="3" style="text-align:left"><span data-line="430"></span>                        </td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="431" data-row="6" data-col="1" style="text-align:left"><span data-line="431"></span> packet from   </td><td class="tbody tr-even col cell-border-left col-even" data-line="431" data-row="6" data-col="2" style="text-align:left"><span data-line="431"></span>               </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="431" data-row="6" data-col="3" style="text-align:left"><span data-line="431"></span>                        </td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="432" data-row="7" data-col="1" style="text-align:left"><span data-line="432"></span> port loopback </td><td class="tbody tr-odd col cell-border-left col-even" data-line="432" data-row="7" data-col="2" style="text-align:left"><span data-line="432"></span>               </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="432" data-row="7" data-col="3" style="text-align:left"><span data-line="432"></span>                        </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="433" data-row="7" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-line col-even" data-line="433" data-row="7" data-col="2" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-odd col-last" data-line="433" data-row="7" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="434" data-row="8" data-col="1" style="text-align:left"><span data-line="434"></span> packet from   </td><td class="tbody tr-even col cell-border-left col-even" data-line="434" data-row="8" data-col="2" style="text-align:left"><span data-line="434"></span> main, with    </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="434" data-row="8" data-col="3" style="text-align:left"><span data-line="434"></span> Zero or more mirrored  </td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="435" data-row="9" data-col="1" style="text-align:left"><span data-line="435"></span> message processing </td><td class="tbody tr-odd col cell-border-left col-even" data-line="435" data-row="9" data-col="2" style="text-align:left"><span data-line="435"></span> direction </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="435" data-row="9" data-col="3" style="text-align:left"><span data-line="435"></span> packets, plus at most </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="436" data-row="9" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left col-even" data-line="436" data-row="9" data-col="2" style="text-align:left"><span data-line="436"></span>               </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="436" data-row="9" data-col="3" style="text-align:left"><span data-line="436"></span> </td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="437" data-row="10" data-col="1" style="text-align:left"><span data-line="437"></span> packet from   </td><td class="tbody tr-even col cell-border-left col-even" data-line="437" data-row="10" data-col="2" style="text-align:left"><span data-line="437"></span> <span data-line="437"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">HOST_TO_NET</code><span data-line="437"></span> </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="437" data-row="10" data-col="3" style="text-align:left"><span data-line="437"></span> one of: a host-to-net  </td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="438" data-row="11" data-col="1" style="text-align:left"><span data-line="438"></span> host-to-net   </td><td class="tbody tr-odd col cell-border-left col-even" data-line="438" data-row="11" data-col="2" style="text-align:left"><span data-line="438"></span>               </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="438" data-row="11" data-col="3" style="text-align:left"><span data-line="438"></span> recirculated packet,   </td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="439" data-row="12" data-col="1" style="text-align:left"><span data-line="439"></span> recirculate   </td><td class="tbody tr-even col cell-border-left col-even" data-line="439" data-row="12" data-col="2" style="text-align:left"><span data-line="439"></span>               </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="439" data-row="12" data-col="3" style="text-align:left"><span data-line="439"></span> or one to-net packet.  </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="440" data-row="12" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left col-even" data-line="440" data-row="12" data-col="2" style="text-align:left"><span data-line="440"></span>               </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="440" data-row="12" data-col="3" style="text-align:left"><span data-line="440"></span>                        </td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="441" data-row="13" data-col="1" style="text-align:left"><span data-line="441"></span> packet from   </td><td class="tbody tr-odd col cell-border-left col-even" data-line="441" data-row="13" data-col="2" style="text-align:left"><span data-line="441"></span>               </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="441" data-row="13" data-col="3" style="text-align:left"><span data-line="441"></span>                        </td></tr>
<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-line="442" data-row="14" data-col="1" style="text-align:left"><span data-line="442"></span> host loopback </td><td class="tbody tr-even tr-last col cell-border-left col-even" data-line="442" data-row="14" data-col="2" style="text-align:left"><span data-line="442"></span>               </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-odd col-last" data-line="442" data-row="14" data-col="3" style="text-align:left"><span data-line="442"></span>                        </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="443" data-row="14" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-line="443" data-row="14" data-col="2" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-line="443" data-row="14" data-col="3" style="text-align:left"></td></tr></tbody></table>
<hr  class="figureline madoko" data-line="444" style="display:block">

<div class="p noindent" data-line="445"><span data-line="445"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Table&#160;<span class="table-label">1</span>.</strong>&#160;</span><span class="caption-text">Result of packet processed one time by main.</span></fig-caption></div></figure>
<p class="p indent" data-line="447"><span data-line="447"></span>Note that each mirrored packet that results from <span data-line="447"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet</code><span data-line="447"></span>
operations will have its own next place that it will go to be
processed, independent of the original packet, and independent of any
other mirror copies made of the same original packet.
</p><h2 id="sec-pna-data-types" class="h1" data-line="452" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="452"></span><span class="heading-before"><span class="heading-label">4</span>.&#8194;</span><span data-line="452"></span>PNA Data types</h2><h3 id="sec-pna-type-definitions" class="h2" data-line="454" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="454"></span><span class="heading-before"><span class="heading-label">4.1</span>.&#8194;</span><span data-line="454"></span>PNA type definitions</h3>
<p class="p noindent" data-line="456"><span data-line="456"></span>Each PNA implementation will have specific bit widths in the data
plane for the types shown in the code excerpt of Section
<span data-line="458"></span><a href="#sec-pna-type-definitions-code" title="4.1.1.&#8194;PNA type definition code excerpt" class="localref" style="target-element:h3"><span class="heading-label">4.1.1</span></a><span data-line="458"></span>.  These widths are defined in the
target specific <span data-line="459"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna.p4</code><span data-line="459"></span> include file.  They are expected to differ
from one PNA implementation to another<span data-line="460"></span><sup id="back-fn-pnap4targetspecific" ><a href="#fn-pnap4targetspecific" title="3.It is expected that pna.p4 include files for
different targets will be nearly identical to each
other.  Besides the possibility of differing bit widths for these
PNA types, the only expected differences between pna.p4 files
for different targets would be annotations on externs, etc. that
the P4 compiler for that target needs to do its job.
&#8617;" class="footnote-ref localref" ><span class="footnote-label">3</span></a></sup><span data-line="460"></span>.
</p>
<p class="p indent" data-line="469"><span data-line="469"></span>For each of these types, the P4 Runtime API<span data-line="469"></span><sup id="back-fn-p4runtimeapi" ><a href="#fn-p4runtimeapi" title="4.The P4Runtime Specification can be found here:
https://&#8203;p4.&#8203;org/&#8203;specs
&#8617;" class="footnote-ref localref" ><span class="footnote-label">4</span></a></sup><span data-line="469"></span> may use bit
widths independent of the targets. These widths are defined by the P4
Runtime API specification, and they are expected to be at least as
large as the corresponding <span data-line="472"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">InHeader_t</code><span data-line="472"></span> type below, such that they
hold a value for any target. All PNA implementations must use data
plane sizes for these types no wider than the corresponding
<span data-line="475"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">InHeader_t</code><span data-line="475"></span>-defined types.
</p><h4 id="sec-pna-type-definitions-code" class="h3" data-line="480" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="480"></span><span class="heading-before"><span class="heading-label">4.1.1</span>.&#8194;</span><span data-line="480"></span>PNA type definition code excerpt</h4>
<div class="p4example" data-line="482" style="padding:6pt;margin-top:6pt;margin-bottom:6pt;border:solid;background-color:#ffffdd;border-width:0.5pt">
<div class="p4exampleblock" data-line="483;pna.p4:168">
<pre class="para-block pre-fenced pre-fenced4 language-p4 lang-p4 p4 colorized" data-line="483;pna.p4:169" data-line-first="483;pna.p4:170" style="display:block;font-family:monospace;font-size:10pt"><code data-line="483;pna.p4:170"><span style="color:darkgreen">/*</span><span style="color:darkgreen"> These are defined using `typedef`, not `type`, so they are truly</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> just different names for the type bit&lt;W&gt; for the particular width W</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> shown.  Unlike the `type` definitions below, values declared with</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> the `typedef` type names can be freely mingled in expressions, just</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> as any value declared with type bit&lt;W&gt; can.  Values declared with</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> one of the `type` names below _cannot_ be so freely mingled, unless</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> you first cast them to the corresponding `typedef` type.  While</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> that may be inconvenient when you need to do arithmetic on such</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> values, it is the price to pay for having all occurrences of values</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> of the `type` types marked as such in the automatically generated</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> control plane API.</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> Note that the width of typedef &lt;name&gt;Uint_t will always be the same</span>
<span style="color:darkgreen"> </span><span style="color:darkgreen">*</span><span style="color:darkgreen"> as the width of type &lt;name&gt;_t. </span><span style="color:darkgreen">*/</span>
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; PortIdUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; InterfaceIdUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; MulticastGroupUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; MirrorSessionIdUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; MirrorSlotIdUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; ClassOfServiceUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; PacketLengthUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; MulticastInstanceUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; TimestampUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; FlowIdUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; ExpireTimeProfileIdUint_t;
<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; PassNumberUint_t;

<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">bit</span>&lt;unspecified&gt; SecurityAssocIdUint_t;

<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/PortId_t&quot;, 32)</span>
type PortIdUint_t         PortId_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/InterfaceId_t&quot;, 32)</span>
type InterfaceIdUint_t     InterfaceId_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/MulticastGroup_t&quot;, 32)</span>
type MulticastGroupUint_t MulticastGroup_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/MirrorSessionId_t&quot;, 16)</span>
type MirrorSessionIdUint_t MirrorSessionId_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/MirrorSlotId_t&quot;, 8)</span>
type MirrorSlotIdUint_t MirrorSlotId_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/ClassOfService_t&quot;, 8)</span>
type ClassOfServiceUint_t ClassOfService_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/PacketLength_t&quot;, 16)</span>
type PacketLengthUint_t   PacketLength_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/MulticastInstance_t&quot;, 16)</span>
type MulticastInstanceUint_t MulticastInstance_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/Timestamp_t&quot;, 64)</span>
type TimestampUint_t      Timestamp_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/FlowId_t&quot;, 32)</span>
type FlowIdUint_t      FlowId_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/ExpireTimeProfileId_t&quot;, 8)</span>
type ExpireTimeProfileIdUint_t      ExpireTimeProfileId_t;
<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/PassNumber_t&quot;, 8)</span>
type PassNumberUint_t      PassNumber_t;

<span style="color:gray">@</span><span style="color:gray">p4runtime_translation</span><span style="color:maroon">(&quot;p4.org/pna/v1/SecurityAssocId_t&quot;, 64)</span>
type SecurityAssocIdUint_t      SecurityAssocId_t;

<span style="color:blue;font-weight:bold">typedef</span> <span style="color:teal;font-weight:bold">error</span>   ParserError_t;

<span style="color:teal;font-weight:bold">const</span> InterfaceId_t PNA_PORT_CPU = (PortId_t) unspecified;

<span style="color:teal;font-weight:bold">const</span> MirrorSessionId_t PNA_MIRROR_SESSION_TO_CPU = (MirrorSessiontId_t) unspecified;</code></pre></div></div><h4 id="sec-pna-port-types-and-values" class="h3" data-line="486" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="486"></span><span class="heading-before"><span class="heading-label">4.1.2</span>.&#8194;</span><span data-line="486"></span>PNA port types and values</h4>
<p class="p noindent" data-line="488"><span data-line="488"></span>There are two types defined by PNA for holding different kinds of
ports: <span data-line="489"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PortId_t</code><span data-line="489"></span> and <span data-line="489"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">InterfaceId_t</code><span data-line="489"></span>.
</p>
<p class="p indent" data-line="491"><span data-line="491"></span>The type <span data-line="491"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PortId_t</code><span data-line="491"></span> must be large enough in the data plane to hold one
of these values:
</p>
<ul class="ul list-plus compact" data-line="494">
<li class="li ul-li list-plus-li compact-li" data-line="494"><span data-line="494"></span>a data plane id for one network port
</li>
<li class="li ul-li list-plus-li compact-li" data-line="495"><span data-line="495"></span>a data plane id for one vport
</li></ul>

<p class="p noindent" data-line="497"><span data-line="497"></span>As one example, a PNA target with four Ethernet network ports could
choose to use the values 0 through 3 to identify the network ports,
and the values 4 through 1023 to identify vports.
</p>
<p class="p indent" data-line="501"><span data-line="501"></span>PNA makes no requirement that the numeric values identifying network
ports must be consecutive, nor for vports.  PNA only requires that for
every possible numeric value <span data-line="503"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="503"></span> with type <span data-line="503"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PortId_t</code><span data-line="503"></span>, exactly one of
these statements is true:
</p>
<ul class="ul list-plus compact" data-line="506">
<li class="li ul-li list-plus-li compact-li" data-line="506"><span data-line="506"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="506"></span> is the data plane id of one network port, but not any vport
</li>
<li class="li ul-li list-plus-li compact-li" data-line="507"><span data-line="507"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="507"></span> is the data plane id of one vport, but not any network port
</li>
<li class="li ul-li list-plus-li compact-li" data-line="508"><span data-line="508"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="508"></span> is the data plane id of no port, neither a network port nor a vport
</li></ul>
<h3 id="sec-pna-supported-metadata-types" class="h2" data-line="510" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="510"></span><span class="heading-before"><span class="heading-label">4.2</span>.&#8194;</span><span data-line="510"></span>PNA supported metadata types</h3>
<div class="p4example" data-line="512" style="padding:6pt;margin-top:6pt;margin-bottom:6pt;border:solid;background-color:#ffffdd;border-width:0.5pt">
<div class="p4exampleblock" data-line="513;pna.p4:629">
<pre class="para-block pre-fenced pre-fenced4 language-p4 lang-p4 p4 colorized" data-line="513;pna.p4:630" data-line-first="513;pna.p4:631" style="display:block;font-family:monospace;font-size:10pt"><code data-line="513;pna.p4:631"><span style="color:teal;font-weight:bold">enum</span> PNA_PacketPath_t {
    <span style="color:darkgreen">// TBD if this type remains, whether it should be an enum or</span>
    <span style="color:darkgreen">// several separate fields representing the same cases in a</span>
    <span style="color:darkgreen">// different form.</span>
    FROM_NET_PORT,
    FROM_NET_LOOPEDBACK,
    FROM_NET_RECIRCULATED,
    FROM_HOST,
    FROM_HOST_LOOPEDBACK,
    FROM_HOST_RECIRCULATED
}

<span style="color:teal;font-weight:bold">struct</span> pna_pre_input_metadata_t {
    PortId_t                 input_port;
    ParserError_t            parser_error;
    PNA_Direction_t          direction;
    PassNumber_t             pass;
    <span style="color:teal;font-weight:bold">bool</span>                     loopedback;
}

<span style="color:teal;font-weight:bold">struct</span> pna_pre_output_metadata_t {
    <span style="color:teal;font-weight:bold">bool</span>                     decrypt;  <span style="color:darkgreen">// TBD: or use said==0 to mean no decrypt?</span>

    <span style="color:darkgreen">// The following things are stored internally within the decrypt</span>
    <span style="color:darkgreen">// block, in a table indexed by said:</span>

    <span style="color:darkgreen">// + The decryption algorithm, e.g. AES256, etc.</span>
    <span style="color:darkgreen">// + The decryption key</span>
    <span style="color:darkgreen">// + Any read-modify-write state in the data plane used to</span>
    <span style="color:darkgreen">//   implement anti-replay attack detection.</span>

    SecurityAssocId_t        said;
    <span style="color:teal;font-weight:bold">bit</span>&lt;<span class="constant" style="color:purple">16</span>&gt;                  decrypt_start_offset;  <span style="color:darkgreen">// in bytes?</span>

    <span style="color:darkgreen">// TBD whether it is important to explicitly pass information to a</span>
    <span style="color:darkgreen">// decryption extern in a way visible to a P4 program about where</span>
    <span style="color:darkgreen">// headers were parsed and found.  An alternative is to assume</span>
    <span style="color:darkgreen">// that the architecture saves the pre parser results somewhere,</span>
    <span style="color:darkgreen">// in a way not visible to the P4 program.</span>
}

<span style="color:teal;font-weight:bold">struct</span> pna_main_parser_input_metadata_t {
    <span style="color:darkgreen">// common fields initialized for all packets that are input to main</span>
    <span style="color:darkgreen">// parser, regardless of direction.</span>
    PNA_Direction_t          direction;
    PassNumber_t             pass;
    <span style="color:teal;font-weight:bold">bool</span>                     loopedback;
    <span style="color:darkgreen">// If this packet has direction NET_TO_HOST, input_port contains</span>
    <span style="color:darkgreen">// the id of the network port on which the packet arrived.</span>
    <span style="color:darkgreen">// If this packet has direction HOST_TO_NET, input_port contains</span>
    <span style="color:darkgreen">// the id of the vport from which the packet came</span>
    PortId_t                 input_port;   <span style="color:darkgreen">// network port id</span>
}

<span style="color:teal;font-weight:bold">struct</span> pna_main_input_metadata_t {
    <span style="color:darkgreen">// common fields initialized for all packets that are input to main</span>
    <span style="color:darkgreen">// parser, regardless of direction.</span>
    PNA_Direction_t          direction;
    PassNumber_t             pass;
    <span style="color:teal;font-weight:bold">bool</span>                     loopedback;
    Timestamp_t              timestamp;
    ParserError_t            parser_error;
    ClassOfService_t         class_of_service;
    <span style="color:darkgreen">// See comments for field input_port in struct</span>
    <span style="color:darkgreen">// pna_main_parser_input_metadata_t</span>
    PortId_t                 input_port;
}


<span style="color:teal;font-weight:bold">struct</span> pna_main_output_metadata_t {
  <span style="color:darkgreen">// common fields used by the architecture to decide what to do with</span>
  <span style="color:darkgreen">// the packet next, after the main parser, control, and deparser</span>
  <span style="color:darkgreen">// have finished executing one pass, regardless of the direction.</span>
  ClassOfService_t         class_of_service; <span style="color:darkgreen">// 0</span>
}
</code></pre></div></div><h3 id="sec-match-kinds" class="h2" data-line="516" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="516"></span><span class="heading-before"><span class="heading-label">4.3</span>.&#8194;</span><span data-line="516"></span>Match kinds</h3>
<div class="tbd" data-line="517" style="color:red">
<div class="tbdblock" data-line="518">
<p class="p noindent" data-line="519"><span data-line="519"></span>TBD: Consider simply referencing the corresponding section of the PSA
specification for this, unless we want to have something different in
PNA.</p></div></div><h3 id="sec-data-plane-vs-control-plane-values" class="h2" data-line="523" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="523"></span><span class="heading-before"><span class="heading-label">4.4</span>.&#8194;</span><span data-line="523"></span>Data plane vs. control plane data representations</h3><h2 id="sec-programmable-blocks" class="h1" data-line="525" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="525"></span><span class="heading-before"><span class="heading-label">5</span>.&#8194;</span><span data-line="525"></span>Programmable blocks</h2>
<p class="p noindent" data-line="527"><span data-line="527"></span>The following declarations provide a template for the programmable
blocks in the PNA. The P4 programmer is responsible for implementing
controls that match these interfaces and instantiate them in a package
definition.
</p>
<p class="p indent" data-line="532"><span data-line="532"></span>It uses the same user-defined metadata type <span data-line="532"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">IM</code><span data-line="532"></span> and header type <span data-line="532"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">IH</code><span data-line="532"></span>
for all ingress parsers and control blocks.  The egress parser and
control blocks can use the same types for those things, or different
types, as the P4 program author wishes.
</p>
<div class="p4example" data-line="537" style="padding:6pt;margin-top:6pt;margin-bottom:6pt;border:solid;background-color:#ffffdd;border-width:0.5pt">
<div class="p4exampleblock" data-line="538;pna.p4:770">
<pre class="para-block pre-fenced pre-fenced4 language-p4 lang-p4 p4 colorized" data-line="538;pna.p4:771" data-line-first="538;pna.p4:772" style="display:block;font-family:monospace;font-size:10pt"><code data-line="538;pna.p4:772"><span style="color:blue;font-weight:bold">control</span> PreControlT&lt;PH, PM&gt;(
    <span style="color:teal;font-weight:bold">in</span>    PH pre_hdr,
    <span style="color:teal;font-weight:bold">inout</span> PM pre_user_meta,
    <span style="color:teal;font-weight:bold">in</span>    pna_pre_input_metadata_t  istd,
    <span style="color:teal;font-weight:bold">inout</span> pna_pre_output_metadata_t ostd);

<span style="color:blue;font-weight:bold">parser</span> MainParserT&lt;PM, MH, MM&gt;(
    packet_in pkt,
    <span style="color:darkgreen">//in    PM pre_user_meta,</span>
    <span style="color:teal;font-weight:bold">out</span>   MH main_hdr,
    <span style="color:teal;font-weight:bold">inout</span> MM main_user_meta,
    <span style="color:teal;font-weight:bold">in</span>    pna_main_parser_input_metadata_t istd);

<span style="color:blue;font-weight:bold">control</span> MainControlT&lt;PM, MH, MM&gt;(
    <span style="color:darkgreen">//in    PM pre_user_meta,</span>
    <span style="color:teal;font-weight:bold">inout</span> MH main_hdr,
    <span style="color:teal;font-weight:bold">inout</span> MM main_user_meta,
    <span style="color:teal;font-weight:bold">in</span>    pna_main_input_metadata_t  istd,
    <span style="color:teal;font-weight:bold">inout</span> pna_main_output_metadata_t ostd);

<span style="color:blue;font-weight:bold">control</span> MainDeparserT&lt;MH, MM&gt;(
    packet_out pkt,
    <span style="color:teal;font-weight:bold">in</span>    MH main_hdr,
    <span style="color:teal;font-weight:bold">in</span>    MM main_user_meta,
    <span style="color:teal;font-weight:bold">in</span>    pna_main_output_metadata_t ostd);

<span style="color:blue;font-weight:bold">package</span> PNA_NIC&lt;PH, PM, MH, MM&gt;(
    MainParserT&lt;PM, MH, MM&gt; main_parser,
    PreControlT&lt;PH, PM&gt; pre_control,
    MainControlT&lt;PM, MH, MM&gt; main_control,
    MainDeparserT&lt;MH, MM&gt; main_deparser);</code></pre></div></div><h2 id="packet-path-details" class="h1" data-line="541" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="541"></span><span class="heading-before"><span class="heading-label">6</span>.&#8194;</span><span data-line="541"></span>Packet Path Details</h2>
<p class="p noindent" data-line="543"><span data-line="543"></span>Refer to section<span data-line="543"></span>&nbsp;<a href="#packet-paths" title="3.&#8194;Packet paths" class="localref" style="target-element:h1"><span class="heading-label">3</span></a><span data-line="543"></span> for the packet paths provided by PNA.
</p>
<div class="tbd" data-line="545" style="color:red">
<div class="tbdblock" data-line="546">
<p class="p noindent" data-line="547"><span data-line="547"></span>TBD: Need to decide where multicast replication can occur, and in what
conditions.</p></div></div>
<div class="tbd" data-line="550" style="color:red">
<div class="tbdblock" data-line="551">
<p class="p noindent" data-line="552"><span data-line="552"></span>TBD: Need to decide where packet mirroring occurs, and in what
conditions, and how the mirrored packets differ from the originals.</p></div></div><h3 id="sec-initial-values-of-packets-processed-by-main-parser" class="h2" data-line="555" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="555"></span><span class="heading-before"><span class="heading-label">6.1</span>.&#8194;</span><span data-line="555"></span>Initial values of packets processed by main parser</h3><h4 id="sec-initial-packet-contents-for-packets-from-ports" class="h3" data-line="563" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="563"></span><span class="heading-before"><span class="heading-label">6.1.1</span>.&#8194;</span><span data-line="563"></span>Initial packet contents for packets from ports</h4>
<p class="p noindent" data-line="565"><span data-line="565"></span>Packet is as received from Ethernet port.
</p>
<p class="p indent" data-line="567"><span data-line="567"></span>User-defined metadata is empty?
</p><h4 id="sec-initial-packet-contents-for-packets-looped-back-from-host-to-network-path" class="h3" data-line="569" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="569"></span><span class="heading-before"><span class="heading-label">6.1.2</span>.&#8194;</span><span data-line="569"></span>Initial packet contents for packets looped back from host-to-network path</h4>
<p class="p noindent" data-line="571"><span data-line="571"></span>Packet is as came out of host-to-net received from Ethernet port.
</p>
<p class="p indent" data-line="573"><span data-line="573"></span>There can be user-defined metadata included with these packets.
</p><h3 id="sec-behavior-of-packets-after-pre-block-is-complete" class="h2" data-line="575" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="575"></span><span class="heading-before"><span class="heading-label">6.2</span>.&#8194;</span><span data-line="575"></span>Behavior of packets after pre block is complete</h3>
<p class="p noindent" data-line="577"><span data-line="577"></span>Cases: drop vs. not, do something in net-to-host inline extern block
or not.
</p><h3 id="sec-initial-values-of-packets-processed-in-network-to-host-direction-by-main-block" class="h2" data-line="580" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="580"></span><span class="heading-before"><span class="heading-label">6.3</span>.&#8194;</span><span data-line="580"></span>Initial values of packets processed in network-to-host direction by main block</h3><h4 id="sec-initial-packet-contents-for-normal-packets" class="h3" data-line="582" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="582"></span><span class="heading-before"><span class="heading-label">6.3.1</span>.&#8194;</span><span data-line="582"></span>Initial packet contents for normal packets</h4>
<p class="p noindent" data-line="584"><span data-line="584"></span>The packet should be either:
+ exactly as arrived at the pre parser, if the net-to-host inline
  extern was directed not to modify the packet
+ exact as output by the net-to-host inline extern
</p>
<p class="p indent" data-line="589"><span data-line="589"></span>The user-defined metadata should be exactly as output by the pre
control.
</p>
<p class="p indent" data-line="592"><span data-line="592"></span>The standard metadata contents should be specified in detail here.
</p><h4 id="sec-initial-packet-contents-for-recirculated-packets" class="h3" data-line="594" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="594"></span><span class="heading-before"><span class="heading-label">6.3.2</span>.&#8194;</span><span data-line="594"></span>Initial packet contents for recirculated packets</h4>
<p class="p noindent" data-line="596"><span data-line="596"></span>Give any differences between this case and previous section.
</p><h3 id="sec-behavior-of-packets-after-main-block-is-complete-in-network-to-host-direction" class="h2" data-line="598" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="598"></span><span class="heading-before"><span class="heading-label">6.4</span>.&#8194;</span><span data-line="598"></span>Behavior of packets after main block is complete in network-to-host direction</h3>
<p class="p noindent" data-line="600"><span data-line="600"></span>Cases: drop, recirculate, loopback to host-to-net direction, to
message processing.  Describe the conditions in which each occurs.
</p><h3 id="sec-initial-values-of-packets-processed-in-host-to-network-direction-by-main-block" class="h2" data-line="603" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="603"></span><span class="heading-before"><span class="heading-label">6.5</span>.&#8194;</span><span data-line="603"></span>Initial values of packets processed in host-to-network direction by main block</h3><h4 id="sec-initial-packet-contents-for-normal-packets" class="h3" data-line="605" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="605"></span><span class="heading-before"><span class="heading-label">6.5.1</span>.&#8194;</span><span data-line="605"></span>Initial packet contents for normal packets</h4>
<p class="p noindent" data-line="607"><span data-line="607"></span>This is for packets from the message processing block.
</p><h4 id="sec-initial-packet-contents-for-recirculated-packets" class="h3" data-line="609" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="609"></span><span class="heading-before"><span class="heading-label">6.5.2</span>.&#8194;</span><span data-line="609"></span>Initial packet contents for recirculated packets</h4>
<p class="p noindent" data-line="611"><span data-line="611"></span>Give any differences between this case and previous section.
</p><h4 id="sec-initial-packet-contents-for-packets-looped-back-after-network-to-host-main-processing" class="h3" data-line="613" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="613"></span><span class="heading-before"><span class="heading-label">6.5.3</span>.&#8194;</span><span data-line="613"></span>Initial packet contents for packets looped back after network-to-host main processing</h4><h3 id="sec-behavior-of-packets-after-main-block-is-complete-in-host-to-network-direction" class="h2" data-line="615" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="615"></span><span class="heading-before"><span class="heading-label">6.6</span>.&#8194;</span><span data-line="615"></span>Behavior of packets after main block is complete in host-to-network direction</h3>
<p class="p noindent" data-line="617"><span data-line="617"></span>Cases: drop, recirculate, to queues.  Describe the conditions in which
each occurs.
</p><h3 id="sec-contents-of-packets-sent-out-to-ports" class="h2" data-line="620" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="620"></span><span class="heading-before"><span class="heading-label">6.7</span>.&#8194;</span><span data-line="620"></span>Contents of packets sent out to ports</h3><h3 id="sec-functions-for-directing-packets" class="h2" data-line="622" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="622"></span><span class="heading-before"><span class="heading-label">6.8</span>.&#8194;</span><span data-line="622"></span>Functions for directing packets</h3><h4 id="sec-extern-function-send_to_port" class="h3" data-line="624" data-heading-depth="3" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="624"></span><span class="heading-before"><span class="heading-label">6.8.1</span>.&#8194;</span><span data-line="624"></span>Extern function <span data-line="624"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port</code></h4>
<div class="p4example" data-line="626" style="padding:6pt;margin-top:6pt;margin-bottom:6pt;border:solid;background-color:#ffffdd;border-width:0.5pt">
<div class="p4exampleblock" data-line="627">
<pre class="para-block pre-fenced pre-fenced4 language-p4 lang-p4 p4 colorized" data-line="628" data-line-first="629" style="display:block;font-family:monospace;font-size:10pt"><code data-line="629"><span style="color:blue;font-weight:bold">extern</span> <span style="color:teal;font-weight:bold">void</span> send_to_port(PortId_t dest_port);</code></pre></div></div>
<p class="p noindent" data-line="630"><span data-line="630"></span>The extern function <span data-line="630"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port</code><span data-line="630"></span> is used to direct a packet to a
specified network port, or to a vport.  Invoking <span data-line="631"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port(x)</code><span data-line="631"></span> is
supported only within the main control.  There are four cases to
consider, detailed below.
</p>
<ul class="ul list-plus compact" data-line="635">
<li class="li ul-li list-plus-li compact-li" data-line="635"><span data-line="635"></span>current packet direction is <span data-line="635"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">HOST_TO_NET</code><span data-line="635"></span>, and <span data-line="635"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="635"></span> is a network port id.
</li></ul>

<p class="p noindent" data-line="637"><span data-line="637"></span>Calling <span data-line="637"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port(x)</code><span data-line="637"></span> modifies hidden state for this packet, so
that the packet will be transmitted out of the network port with id
<span data-line="639"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="639"></span>, without being looped back.
</p>
<ul class="ul list-plus compact" data-line="641">
<li class="li ul-li list-plus-li compact-li" data-line="641"><span data-line="641"></span>current packet direction is <span data-line="641"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NET_TO_HOST</code><span data-line="641"></span>, and <span data-line="641"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="641"></span> is a network port id.
</li></ul>

<p class="p noindent" data-line="643"><span data-line="643"></span>Calling <span data-line="643"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port(x)</code><span data-line="643"></span> modifies hidden state for this packet, so
that when the packet is finished with the main control and main
deparser, it will loop back in the host side, and later return to
be processed by the main control in the HOST<span data-line="646"></span>_<span data-line="646"></span>TO<span data-line="646"></span>_<span data-line="646"></span>NET direction.  The
hidden state will remain associated with the packet during that
loopback, so that even if no further forwarding functions are
called for the packet, it will be transmitted out of network port
<span data-line="650"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="650"></span>.
</p>
<ul class="ul list-plus compact" data-line="652">
<li class="li ul-li list-plus-li compact-li" data-line="652"><span data-line="652"></span>current packet direction is <span data-line="652"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">HOST_TO_NET</code><span data-line="652"></span>, and <span data-line="652"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="652"></span> is a vport id.
</li></ul>

<p class="p noindent" data-line="654"><span data-line="654"></span>Calling <span data-line="654"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port(x)</code><span data-line="654"></span> modifies hidden state for this packet, so
that when the packet is finished with the main control and main
deparser, it will take the port loopback path, and later return to
be processed by the main control in the NET<span data-line="657"></span>_<span data-line="657"></span>TO<span data-line="657"></span>_<span data-line="657"></span>HOST direction.  The
hidden state will remain associated with the packet during that
loopback, so that even if no further forwarding functions are
called for the packet, it will be sent to the vport with id <span data-line="660"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="660"></span> in
the host.
</p>
<ul class="ul list-plus compact" data-line="663">
<li class="li ul-li list-plus-li compact-li" data-line="663"><span data-line="663"></span>current packet direction is <span data-line="663"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NET_TO_HOST</code><span data-line="663"></span>, and <span data-line="663"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="663"></span> is a vport id.
</li></ul>

<p class="p noindent" data-line="665"><span data-line="665"></span>Calling <span data-line="665"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port(x)</code><span data-line="665"></span> modifies hidden state for this packet, so
that the packet will be sent to the vport with id <span data-line="666"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">x</code><span data-line="666"></span> in the host,
without being looped back.
</p><h3 id="sec-packet-mirroring" class="h2" data-line="669" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="669"></span><span class="heading-before"><span class="heading-label">6.9</span>.&#8194;</span><span data-line="669"></span>Packet Mirroring</h3>
<div class="p4example" data-line="671" style="padding:6pt;margin-top:6pt;margin-bottom:6pt;border:solid;background-color:#ffffdd;border-width:0.5pt">
<div class="p4exampleblock" data-line="672">
<pre class="para-block pre-fenced pre-fenced4 language-p4 lang-p4 p4 colorized" data-line="673" data-line-first="674" style="display:block;font-family:monospace;font-size:10pt"><code data-line="674"><span style="color:blue;font-weight:bold">extern</span> <span style="color:teal;font-weight:bold">void</span> mirror_packet(MirrorSlotId_t mirror_slot_id,
                          MirrorSessionId_t mirror_session_id);</code></pre></div></div>
<p class="p noindent" data-line="676"><span data-line="676"></span>The extern function <span data-line="676"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet</code><span data-line="676"></span> is used to cause a mirror copy of
the packet currently being processed to be created.  Invoking
<span data-line="678"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet(x)</code><span data-line="678"></span> is supported only within the main control.
</p>
<p class="p indent" data-line="680"><span data-line="680"></span>PNA enables multiple mirror copies of a packet to be created during a
single execution of <span data-line="681"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="681"></span>, by calling <span data-line="681"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet</code><span data-line="681"></span> with
different mirror slot id values.  PNA targets should support
<span data-line="683"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_slot_id</code><span data-line="683"></span> values in the range 0 through 3, at least, but are
allowed to support a larger range.
</p>
<p class="p indent" data-line="686"><span data-line="686"></span>When <span data-line="686"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="686"></span> begins execution, all mirror slots are initialized
so that they do not create a copy of the packet.
</p>
<p class="p indent" data-line="689"><span data-line="689"></span>After calling <span data-line="689"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet(slot_id, session_id)</code><span data-line="689"></span>, then when the main
control finishes execution, the target will make a best effort to
create a copy of the packet that will be processed according to the
parameters configured by the control plane for the mirror session
numbered <span data-line="693"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">session_id</code><span data-line="693"></span>, for mirror slot <span data-line="693"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">slot_id</code><span data-line="693"></span>.  Note that this is
best effort<span data-line="694"></span> <span data-line="694"></span>&#8211;<span data-line="694"></span> if the target device is already near its upper limit of
its ability to create mirror copies, then some later mirror copies may
not be made, even though the P4 program requested them.
</p>
<p class="p indent" data-line="698"><span data-line="698"></span>Each of the mirror slots is independent of each other.  For example,
calling <span data-line="699"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet(<span class="constant" style="color:purple">1</span>, session_id)</code><span data-line="699"></span> has no effect on mirror slots
0, 2, or 3.
</p>
<p class="p indent" data-line="702"><span data-line="702"></span>Mirror session id 0 is reserved by the architecture, and must not be
used by a P4 developer.
</p>
<p class="p indent" data-line="705"><span data-line="705"></span>If multiple calls are made to <span data-line="705"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet()</code><span data-line="705"></span> for the same mirror
slot id in the same execution of the main control, only the last
<span data-line="707"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">session_id</code><span data-line="707"></span> value is used to create a copy of the packet.  That is,
every call to <span data-line="708"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet(slot_id, session_id)</code><span data-line="708"></span> overwrites the
effects of any earlier to <span data-line="709"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet()</code><span data-line="709"></span> with the same <span data-line="709"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">slot_id</code><span data-line="709"></span>.
</p>
<p class="p indent" data-line="711"><span data-line="711"></span>The effects of <span data-line="711"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet()</code><span data-line="711"></span> calls are independent of calls to
<span data-line="712"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">drop_packet()</code><span data-line="712"></span> and <span data-line="712"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">send_to_port()</code><span data-line="712"></span>.  Regardless of which of those
things is done to the original packet, up to one mirror packet per
mirror slot can be created.
</p>
<p class="p indent" data-line="716"><span data-line="716"></span>The control plane code can configure the following properties of each
mirror session, independently of other mirror sessions:
</p>
<ul class="ul list-plus compact" data-line="719">
<li class="li ul-li list-plus-li compact-li" data-line="719"><span data-line="719"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">packet_contents</code><span data-line="719"></span>
</li></ul>

<p class="p noindent" data-line="721"><span data-line="721"></span>If <span data-line="721"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PRE_MODIFY</code><span data-line="721"></span>, then the mirrored packet<span data-line="721"></span>&#39;<span data-line="721"></span>s contents will be the same
as the original packet as it was when the packet began the execution
of the main control that invoked the <span data-line="723"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet()</code><span data-line="723"></span> function.
</p>
<p class="p indent" data-line="725"><span data-line="725"></span>If <span data-line="725"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">POST_MODIFY</code><span data-line="725"></span>, then the mirrored packet<span data-line="725"></span>&#39;<span data-line="725"></span>s contents will be the same
as the original packet that is being mirrored, after any modifications
made during the execution of the main control that invoked the
<span data-line="728"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet()</code><span data-line="728"></span> function.
</p>
<ul class="ul list-plus compact" data-line="730">
<li class="li ul-li list-plus-li compact-li" data-line="730"><span data-line="730"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">truncate</code><span data-line="730"></span>
</li></ul>

<p class="p noindent" data-line="732"><span data-line="732"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt"><span style="color:blue;font-weight:bold">true</span></code><span data-line="732"></span> to limit the length of the mirrored packet to the
<span data-line="733"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">truncate_length</code><span data-line="733"></span>.  <span data-line="733"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt"><span style="color:blue;font-weight:bold">false</span></code><span data-line="733"></span> to cause the mirrored packet not to be
truncated, in which case the <span data-line="734"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">truncate_length</code><span data-line="734"></span> property is ignored for
this mirror session.
</p>
<ul class="ul list-plus compact" data-line="737">
<li class="li ul-li list-plus-li compact-li" data-line="737"><span data-line="737"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">truncate_length</code><span data-line="737"></span>
</li></ul>

<p class="p noindent" data-line="739"><span data-line="739"></span>In units of bytes.  Targets may limit the choices here, e.g. to a
multiple of 32 bytes, or perhaps even a subset of those choices.
</p>
<ul class="ul list-plus compact" data-line="742">
<li class="li ul-li list-plus-li compact-li" data-line="742"><span data-line="742"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">sampling_method</code><span data-line="742"></span>
</li></ul>

<p class="p noindent" data-line="744"><span data-line="744"></span>One of the values: <span data-line="744"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">RANDOM_SAMPLING</code><span data-line="744"></span>, <span data-line="744"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">HASH_SAMPLING</code><span data-line="744"></span>.
</p>
<p class="p indent" data-line="746"><span data-line="746"></span>If <span data-line="746"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">RANDOM_SAMPLING</code><span data-line="746"></span>, then a mirror copy requested for this mirror
session will only be created with a configured probability given by
the <span data-line="748"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">sample_probability</code><span data-line="748"></span> property.
</p>
<p class="p indent" data-line="750"><span data-line="750"></span>If <span data-line="750"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">HASH_SAMPLING</code><span data-line="750"></span>, then a target-specific hash function will be
calculated over the packet<span data-line="751"></span>&#39;<span data-line="751"></span>s header fields resulting in a hash output
value <span data-line="752"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">H</code><span data-line="752"></span>.  A mirror copy will be created if <span data-line="752"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">(H &amp; sample_hash_mask)
== sample_hash_value</code><span data-line="753"></span>.
</p>
<ul class="ul list-plus compact" data-line="755">
<li class="li ul-li list-plus-li compact-li" data-line="755"><span data-line="755"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">meter_parameters</code><span data-line="755"></span>
</li></ul>

<p class="p noindent" data-line="757"><span data-line="757"></span>If the conditions specified by the <span data-line="757"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">sampling_method</code><span data-line="757"></span> and other
sampling properties are passed, then a P4 meter dedicated for use by
this mirror session will be updated.  If it returns a <span data-line="759"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">GREEN</code><span data-line="759"></span> result,
then the mirror copy will be created (still with best effort, if the
target device<span data-line="761"></span>&#39;<span data-line="761"></span>s implementation is still oversubscribed with requests
to create mirror copies).
</p>
<p class="p indent" data-line="764"><span data-line="764"></span>If the meter update returns any result other than <span data-line="764"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">GREEN</code><span data-line="764"></span>, then no
mirror copy will be created.
</p>
<ul class="ul list-plus compact" data-line="767">
<li class="li ul-li list-plus-li compact-li" data-line="767"><span data-line="767"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">destination_port</code><span data-line="767"></span>
</li></ul>

<p class="p noindent" data-line="769"><span data-line="769"></span>A network port id, or a vport id.
</p>
<p class="p indent" data-line="771"><span data-line="771"></span>If <span data-line="771"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">destination_port</code><span data-line="771"></span> is a network port id, that network port is the
destination of mirrored copy packets created by this session.  If the
<span data-line="773"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet()</code><span data-line="773"></span> call for this session was invoked in the
<span data-line="774"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NET_TO_HOST</code><span data-line="774"></span> direction, mirror copy packets created will loop back in
the host side of the target, and later come back for processing in the
main block in the <span data-line="776"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">HOST_TO_NET</code><span data-line="776"></span> direction, already destined for the
network port <span data-line="777"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">destination_port</code><span data-line="777"></span>.  That port can be overwritten by
calls to forwarding functions.
</p>
<p class="p indent" data-line="780"><span data-line="780"></span>If <span data-line="780"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">destination_port</code><span data-line="780"></span> is a vport id, that vport is the destination of
mirrored copy packets created by this session.  If the
<span data-line="782"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet()</code><span data-line="782"></span> call for this session was invoked in the
<span data-line="783"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">HOST_TO_NET</code><span data-line="783"></span> direction, mirror copy packets created will loop back in
the network port side of the NIC, and later come back for processing
in the main block in the <span data-line="785"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NET_TO_HOST</code><span data-line="785"></span> direction, already destined for
the vport <span data-line="786"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">destination_port</code><span data-line="786"></span>.  That vport can be overwritten by calls
to forwarding functions.
</p>
<div class="tbd" data-line="789" style="color:red">
<div class="tbdblock" data-line="790">
<p class="p noindent" data-line="791"><span data-line="791"></span>TBD: When a mirror copied packet comes back to the main control, it will
have some metadata indicating it is mirror copy.  We should define a
way in PNA to recognize such mirror copies, e.g. some new extern
function call returning true if the packet was created by a
<span data-line="795"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">mirror_packet</code><span data-line="795"></span> operation.</p></div></div><h3 id="sec-packet-recirculation" class="h2" data-line="797" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="797"></span><span class="heading-before"><span class="heading-label">6.10</span>.&#8194;</span><span data-line="797"></span>Packet recirculation</h3><h2 id="sec-pna-extern-objects" class="h1" data-line="799" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="799"></span><span class="heading-before"><span class="heading-label">7</span>.&#8194;</span><span data-line="799"></span>PNA Extern Objects</h2><h3 id="sec-extern-restrictions" class="h2" data-line="801" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="801"></span><span class="heading-before"><span class="heading-label">7.1</span>.&#8194;</span><span data-line="801"></span>Restrictions on where externs may be used</h3>
<p class="p noindent" data-line="803"><span data-line="803"></span>All instantiations in a P4<span data-line="803"></span><sub>16</sub><span data-line="803"></span> program occur at compile time, and can
be arranged in a tree structure we will call the instantiation tree.
The root of the tree <span data-line="805"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">T</code><span data-line="805"></span> represents the top level of the program. Its
child is the node for the package <span data-line="806"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PNA_NIC</code><span data-line="806"></span> described in Section
<span data-line="807"></span><a href="#sec-programmable-blocks" title="5.&#8194;Programmable blocks" class="localref" style="target-element:h1"><span class="heading-label">5</span></a><span data-line="807"></span>, and any externs instantiated at the top
level of the program. The children of the <span data-line="808"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PNA_NIC</code><span data-line="808"></span> node are the
packages and externs passed as parameters to the <span data-line="809"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PNA_NIC</code><span data-line="809"></span>
instantiation. See Figure<span data-line="810"></span>&nbsp;<a href="#fig-instantiation-tree" title="Minimal PNA instantiation tree" class="localref" style="target-element:figure"><span class="figure-label">3</span></a><span data-line="810"></span> for a drawing of
the smallest instantiation tree possible for a P4 program written for
PNA.
</p>
<figure id="fig-instantiation-tree" class="figure floating align-center float" data-line="814" style="text-align:center;float-env:figure;float-name:Figure;page-align:here">

<hr  class="figureline madoko" data-line="816" style="display:block">

<div class="p noindent" data-line="817"><span data-line="817"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">3</span>.</strong>&#160;</span><span class="caption-text">Minimal PNA instantiation tree</span></fig-caption></div></figure>
<p class="p indent" data-line="817"><span data-line="817"></span>If any of those parsers or controls instantiate other parsers,
controls, and/or externs, the instantiation tree contains child nodes
for them, continuing until the instantiation tree is complete.
</p>
<p class="p indent" data-line="821"><span data-line="821"></span>For every instance whose node is a descendant of the <span data-line="821"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Ingress</code><span data-line="821"></span> node in
this tree, call it an <span data-line="822"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Ingress</code><span data-line="822"></span> instance. Similarly for the other
ingress and egress parsers and controls. All other instances are top
level instances.
</p>
<p class="p indent" data-line="826"><span data-line="826"></span>A PNA implementation is allowed to reject programs that instantiate
externs, or attempt to call their methods, from anywhere other than
the places mentioned in Table<span data-line="828"></span>&nbsp;<a href="#table-extern-usage" title="Summary of controls that can instantiate and invoke externs." class="localref" style="target-element:tablefigure"><span class="table-label">2</span></a><span data-line="828"></span>.
</p>
<figure id="table-extern-usage" class="tablefigure floating align-center float" data-line="830" style="text-align:center;float-env:table;float-name:Table"><table class="madoko block" data-line="831">
<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-line="831" data-row="0" data-col="1" style="text-align:left"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-line="831" data-row="0" data-col="2" style="text-align:left"></th></tr>
<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-line="832" data-row="1" data-col="1" style="font-weight:bold;text-align:left"><span data-line="832"></span> Extern type       </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-line="832" data-row="1" data-col="2" style="font-weight:bold;text-align:left"><span data-line="832"></span> Where it may be instantiated and called from </th></tr></thead>
<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-line="834" data-row="1" data-col="1" style="text-align:left"><span data-line="834"></span> <span data-line="834"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">ActionProfile</code><span data-line="834"></span>   </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-line="834" data-row="1" data-col="2" style="text-align:left"><span data-line="834"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-odd tr-first col cell-border-left cell-line col-odd col-first" data-line="835" data-row="1" data-col="1" style="text-align:left"></td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right cell-line col-even col-last" data-line="835" data-row="1" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="836" data-row="2" data-col="1" style="text-align:left"><span data-line="836"></span> <span data-line="836"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">ActionSelector</code><span data-line="836"></span>  </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-line="836" data-row="2" data-col="2" style="text-align:left"><span data-line="836"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="837" data-row="2" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-line="837" data-row="2" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="838" data-row="3" data-col="1" style="text-align:left"><span data-line="838"></span> <span data-line="838"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Checksum</code><span data-line="838"></span>        </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-line="838" data-row="3" data-col="2" style="text-align:left"><span data-line="838"></span> MainParser, MainDeparser </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="839" data-row="3" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-line="839" data-row="3" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="840" data-row="4" data-col="1" style="text-align:left"><span data-line="840"></span> <span data-line="840"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Counter</code><span data-line="840"></span>         </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-line="840" data-row="4" data-col="2" style="text-align:left"><span data-line="840"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="841" data-row="4" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-line="841" data-row="4" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="842" data-row="5" data-col="1" style="text-align:left"><span data-line="842"></span> <span data-line="842"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Digest</code><span data-line="842"></span>          </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-line="842" data-row="5" data-col="2" style="text-align:left"><span data-line="842"></span> MainDeparser </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="843" data-row="5" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-line="843" data-row="5" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="844" data-row="6" data-col="1" style="text-align:left"><span data-line="844"></span> <span data-line="844"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">DirectCounter</code><span data-line="844"></span>   </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-line="844" data-row="6" data-col="2" style="text-align:left"><span data-line="844"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="845" data-row="6" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-line="845" data-row="6" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="846" data-row="7" data-col="1" style="text-align:left"><span data-line="846"></span> <span data-line="846"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">DirectMeter</code><span data-line="846"></span>     </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-line="846" data-row="7" data-col="2" style="text-align:left"><span data-line="846"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="847" data-row="7" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-line="847" data-row="7" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="848" data-row="8" data-col="1" style="text-align:left"><span data-line="848"></span> <span data-line="848"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Hash</code><span data-line="848"></span>            </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-line="848" data-row="8" data-col="2" style="text-align:left"><span data-line="848"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="849" data-row="8" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-line="849" data-row="8" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="850" data-row="9" data-col="1" style="text-align:left"><span data-line="850"></span> <span data-line="850"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">InternetChecksum</code><span data-line="850"></span> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-line="850" data-row="9" data-col="2" style="text-align:left"><span data-line="850"></span> MainParser, MainDeparser </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="851" data-row="9" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-line="851" data-row="9" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="852" data-row="10" data-col="1" style="text-align:left"><span data-line="852"></span> <span data-line="852"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Meter</code><span data-line="852"></span>           </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-line="852" data-row="10" data-col="2" style="text-align:left"><span data-line="852"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="853" data-row="10" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-line="853" data-row="10" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="854" data-row="11" data-col="1" style="text-align:left"><span data-line="854"></span> <span data-line="854"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Random</code><span data-line="854"></span>          </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-line="854" data-row="11" data-col="2" style="text-align:left"><span data-line="854"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="855" data-row="11" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-line="855" data-row="11" data-col="2" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-line="856" data-row="12" data-col="1" style="text-align:left"><span data-line="856"></span> <span data-line="856"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Register</code><span data-line="856"></span>        </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-line="856" data-row="12" data-col="2" style="text-align:left"><span data-line="856"></span> PreControl, MainControl </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="857" data-row="12" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-line="857" data-row="12" data-col="2" style="text-align:left"></td></tr></tbody></table>
<hr  class="figureline madoko" data-line="858" style="display:block">

<div class="p noindent" data-line="859"><span data-line="859"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Table&#160;<span class="table-label">2</span>.</strong>&#160;</span><span class="caption-text">Summary of controls that can instantiate and invoke externs.</span></fig-caption></div></figure>
<p class="p indent" data-line="861"><span data-line="861"></span>For example, <span data-line="861"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Counter</code><span data-line="861"></span> being restricted to <span data-line="861"></span>&#8220;Pre, Main&#8221;<span data-line="861"></span> means that
every <span data-line="862"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Counter</code><span data-line="862"></span> instance must be instantiated within either the <span data-line="862"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PreControl</code><span data-line="862"></span>
control block or the <span data-line="863"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="863"></span> block, or be a descendant of one of
those nodes in the instantiation tree. If a <span data-line="864"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">Counter</code><span data-line="864"></span> instance is
instantiated in Main, for example, then it cannot be referenced, and
thus its methods cannot be called, from any block except <span data-line="866"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="866"></span>
or one of its descendants in the tree.
</p>
<p class="p indent" data-line="869"><span data-line="869"></span>PNA implementations need not support instantiating these externs at
the top level. PNA implementations are allowed to accept programs that
use these externs in other places, but they need not. Thus P4
programmers wishing to maximize the portability of their programs
should restrict their use of these externs to the places indicated in
the table.
</p>
<p class="p indent" data-line="876"><span data-line="876"></span>All methods for type <span data-line="876"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">packet_out</code><span data-line="876"></span>, e.g., <span data-line="876"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">emit</code><span data-line="876"></span>, are restricted to be
within deparser control blocks in PNA, because those are the only
places where an instance of type <span data-line="878"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">packet_out</code><span data-line="878"></span> is visible. Similarly
all methods for type <span data-line="879"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">packet_in</code><span data-line="879"></span>, e.g. <span data-line="879"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">extract</code><span data-line="879"></span> and <span data-line="879"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">advance</code><span data-line="879"></span>, are
restricted to be within parsers in PNA programs. P4<span data-line="880"></span><sub>16</sub><span data-line="880"></span> restricts all
<span data-line="881"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt"><span style="color:blue;font-weight:bold">verify</span></code><span data-line="881"></span> method calls to be within parsers for all P4<span data-line="881"></span><sub>16</sub><span data-line="881"></span> programs,
regardless of whether they are for the PNA.
</p>
<p class="p indent" data-line="884"><span data-line="884"></span>See the PSA specification for definitions of all of these externs.
There is work under way as of this writing that may result in these
extern defintions being moved from the PSA specification into a
separate standard library of P4 extern definitions, and if this is
done, both the PSA and PNA specifications will reference that.
</p><h2 id="sec-pna-table-properties" class="h1" data-line="890" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="890"></span><span class="heading-before"><span class="heading-label">8</span>.&#8194;</span><span data-line="890"></span>PNA Table Properties</h2>
<p class="p noindent" data-line="892"><span data-line="892"></span>Table<span data-line="892"></span>&nbsp;<a href="#table-table-properties" title="Summary of PNA table properties." class="localref" style="target-element:tablefigure"><span class="table-label">3</span></a><span data-line="892"></span> lists all P4 table properties defined
by PNA that are not included in the base P4<span data-line="893"></span><sub>16</sub><span data-line="893"></span> language
specification.
</p>
<figure id="table-table-properties" class="tablefigure floating align-center float" data-line="896" style="text-align:center;float-env:table;float-name:Table"><table class="madoko block" data-line="897">
<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-line="897" data-row="0" data-col="1" style="text-align:left"></th><th class="thead tr-even col cell-border-left cell-line col-even" data-line="897" data-row="0" data-col="2" style="text-align:left"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-line="897" data-row="0" data-col="3" style="text-align:left"></th></tr>
<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-line="898" data-row="1" data-col="1" style="font-weight:bold;text-align:left"><span data-line="898"></span> Property name         </th><th class="col cell-border-left thead tr-odd tr-last tr-first col-even" data-line="898" data-row="1" data-col="2" style="font-weight:bold;text-align:left"><span data-line="898"></span> Type </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-odd col-last" data-line="898" data-row="1" data-col="3" style="font-weight:bold;text-align:left"><span data-line="898"></span> See also </th></tr></thead>
<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-row="0" data-col="2" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-row="0" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-line="900" data-row="1" data-col="1" style="text-align:left"><span data-line="900"></span> <span data-line="900"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_on_miss</code><span data-line="900"></span>         </td><td class="tbody tr-odd tr-first col cell-border-left col-even" data-line="900" data-row="1" data-col="2" style="text-align:left"><span data-line="900"></span> <span data-line="900"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">boolean</code><span data-line="900"></span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-odd col-last" data-line="900" data-row="1" data-col="3" style="text-align:left"><span data-line="900"></span> Section<span data-line="900"></span>&nbsp;<a href="#sec-add-on-miss" title="8.1.&#8194;Tables with add-on-miss capability" class="localref" style="target-element:h2"><span class="heading-label">8.1</span></a><span data-line="900"></span> </td></tr>
<tr><td class="tbody tr-odd tr-first col cell-border-left cell-line col-odd col-first" data-line="901" data-row="1" data-col="1" style="text-align:left"></td><td class="tbody tr-odd tr-first col cell-border-left cell-line col-even" data-line="901" data-row="1" data-col="2" style="text-align:left"></td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right cell-line col-odd col-last" data-line="901" data-row="1" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="902" data-row="2" data-col="1" style="text-align:left"><span data-line="902"></span> <span data-line="902"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_direct_counter</code><span data-line="902"></span> </td><td class="tbody tr-even col cell-border-left col-even" data-line="902" data-row="2" data-col="2" style="text-align:left"><span data-line="902"></span> one <span data-line="902"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">DirectCounter</code><span data-line="902"></span> instance name </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="902" data-row="2" data-col="3" style="text-align:left"><span data-line="902"></span>  </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="903" data-row="2" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-line="903" data-row="2" data-col="2" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-line="903" data-row="2" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="904" data-row="3" data-col="1" style="text-align:left"><span data-line="904"></span> <span data-line="904"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_direct_meter</code><span data-line="904"></span> </td><td class="tbody tr-odd col cell-border-left col-even" data-line="904" data-row="3" data-col="2" style="text-align:left"><span data-line="904"></span> one <span data-line="904"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">DirectMeter</code><span data-line="904"></span> instance name </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="904" data-row="3" data-col="3" style="text-align:left"><span data-line="904"></span>  </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="905" data-row="3" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-line col-even" data-line="905" data-row="3" data-col="2" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-odd col-last" data-line="905" data-row="3" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="906" data-row="4" data-col="1" style="text-align:left"><span data-line="906"></span> <span data-line="906"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_implementation</code><span data-line="906"></span>  </td><td class="tbody tr-even col cell-border-left col-even" data-line="906" data-row="4" data-col="2" style="text-align:left"><span data-line="906"></span> instance name of one <span data-line="906"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">ActionProfile</code><span data-line="906"></span> </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="906" data-row="4" data-col="3" style="text-align:left"><span data-line="906"></span>  </td></tr>
<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-line="907" data-row="5" data-col="1" style="text-align:left"><span data-line="907"></span>                       </td><td class="tbody tr-odd col cell-border-left col-even" data-line="907" data-row="5" data-col="2" style="text-align:left"><span data-line="907"></span> or <span data-line="907"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">ActionSelector</code><span data-line="907"></span> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-odd col-last" data-line="907" data-row="5" data-col="3" style="text-align:left"><span data-line="907"></span>  </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="908" data-row="5" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-line col-even" data-line="908" data-row="5" data-col="2" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-odd col-last" data-line="908" data-row="5" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-line="909" data-row="6" data-col="1" style="text-align:left"><span data-line="909"></span> <span data-line="909"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_empty_group_action</code><span data-line="909"></span> </td><td class="tbody tr-even col cell-border-left col-even" data-line="909" data-row="6" data-col="2" style="text-align:left"><span data-line="909"></span> action </td><td class="tbody tr-even col cell-border-left cell-border-right col-odd col-last" data-line="909" data-row="6" data-col="3" style="text-align:left"><span data-line="909"></span>  </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="910" data-row="6" data-col="1" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-line="910" data-row="6" data-col="2" style="text-align:left"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-line="910" data-row="6" data-col="3" style="text-align:left"></td></tr>
<tr><td class="tbody tr-odd tr-last col cell-border-left col-odd col-first" data-line="911" data-row="7" data-col="1" style="text-align:left"><span data-line="911"></span> <span data-line="911"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_idle_timeout</code><span data-line="911"></span> </td><td class="tbody tr-odd tr-last col cell-border-left col-even" data-line="911" data-row="7" data-col="2" style="text-align:left"><span data-line="911"></span> <span data-line="911"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PNA_IdleTimeout_t</code><span data-line="911"></span> </td><td class="tbody tr-odd tr-last col cell-border-left cell-border-right col-odd col-last" data-line="911" data-row="7" data-col="3" style="text-align:left"><span data-line="911"></span> Section<span data-line="911"></span>&nbsp;<a href="#sec-idle-timeout" title="8.2.&#8194;Table entry timeout notification" class="localref" style="target-element:h2"><span class="heading-label">8.2</span></a><span data-line="911"></span> </td></tr>
<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-line="912" data-row="7" data-col="1" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-line col-even" data-line="912" data-row="7" data-col="2" style="text-align:left"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-odd col-last" data-line="912" data-row="7" data-col="3" style="text-align:left"></td></tr></tbody></table>
<hr  class="figureline madoko" data-line="913" style="display:block">

<div class="p noindent" data-line="914"><span data-line="914"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Table&#160;<span class="table-label">3</span>.</strong>&#160;</span><span class="caption-text">Summary of PNA table properties.</span></fig-caption></div></figure>
<p class="p indent" data-line="916"><span data-line="916"></span>A PNA implementation need not support both of a <span data-line="916"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_implementation</code><span data-line="916"></span>
and <span data-line="917"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_direct_counter</code><span data-line="917"></span> property on the same table.
</p>
<p class="p indent" data-line="919"><span data-line="919"></span>Similarly, a PNA implementation need not support both of a
<span data-line="920"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_implementation</code><span data-line="920"></span> and <span data-line="920"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_direct_meter</code><span data-line="920"></span> property on the same
table.
</p>
<p class="p indent" data-line="923"><span data-line="923"></span>A PNA implementation must implement tables that have both a
<span data-line="924"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_direct_counter</code><span data-line="924"></span> and <span data-line="924"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_direct_meter</code><span data-line="924"></span> property.
</p>
<p class="p indent" data-line="926"><span data-line="926"></span>A PNA implementation need not support both <span data-line="926"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_implementation</code><span data-line="926"></span> and
<span data-line="927"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_idle_timeout</code><span data-line="927"></span> properties on the same table.
</p><h3 id="sec-add-on-miss" class="h2" data-line="929" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="929"></span><span class="heading-before"><span class="heading-label">8.1</span>.&#8194;</span><span data-line="929"></span>Tables with add-on-miss capability</h3>
<p class="p noindent" data-line="931"><span data-line="931"></span>PNA defines the <span data-line="931"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_on_miss</code><span data-line="931"></span> table property.  If the value of this
property is <span data-line="932"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt"><span style="color:blue;font-weight:bold">true</span></code><span data-line="932"></span> for a table, the P4 developer is allowed to define
a default action for the table that calls the <span data-line="933"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_entry</code><span data-line="933"></span> extern
function.  <span data-line="934"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_entry</code><span data-line="934"></span> adds a new entry to the table whose default
action calls the <span data-line="935"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_entry</code><span data-line="935"></span> function.  The new entry will have the
same key that was just looked up.
</p>
<p class="p indent" data-line="938"><span data-line="938"></span>The control plane API is still allowed to add, modify, and delete
entries of such a table, but any entries added via the <span data-line="939"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_entry</code><span data-line="939"></span>
function do not require the control plane software to be involved in
any way.  It is expected that PNA implementations will be able to
sustain <span data-line="942"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_entry</code><span data-line="942"></span> calls at a large fraction of their line rate, but
it need not be at the same packet rate supported for processing
packets that do not call <span data-line="944"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_entry</code><span data-line="944"></span>.  The new table entry will be
matchable when the next packet is processed that applies this table.
</p>
<div class="p4example" data-line="947" style="padding:6pt;margin-top:6pt;margin-bottom:6pt;border:solid;background-color:#ffffdd;border-width:0.5pt">
<div class="p4exampleblock" data-line="948">
<pre class="para-block pre-fenced pre-fenced4 language-p4 lang-p4 p4 colorized" data-line="949" data-line-first="950" style="display:block;font-family:monospace;font-size:10pt"><code data-line="950"><span style="color:blue;font-weight:bold">extern</span> <span style="color:teal;font-weight:bold">bool</span> add_entry&lt;T&gt;(string action_name,
                         <span style="color:teal;font-weight:bold">in</span> T action_params);</code></pre></div></div>
<p class="p noindent" data-line="952"><span data-line="952"></span>It is expected that many PNA implementations will restrict
<span data-line="953"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_entry()</code><span data-line="953"></span> to be called with the following restrictions:
</p>
<ul class="ul list-star compact" data-line="955">
<li class="li ul-li list-star-li compact-li" data-line="955"><span data-line="955"></span>Only from within an action
</li>
<li class="li ul-li list-star-li compact-li" data-line="956"><span data-line="956"></span>Only if the action is a default action of a table with property
<span data-line="957"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">add_on_miss</code><span data-line="957"></span> equal to <span data-line="957"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt"><span style="color:blue;font-weight:bold">true</span></code><span data-line="957"></span>.
</li>
<li class="li ul-li list-star-li compact-li" data-line="958"><span data-line="958"></span>Only for a table with all key fields having match<span data-line="958"></span>_<span data-line="958"></span>kind <span data-line="958"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">exact</code><span data-line="958"></span>.
</li>
<li class="li ul-li list-star-li compact-li" data-line="959"><span data-line="959"></span>Only with an action name that is one of the hit actions of that same
table.  This action has parameters that are all directionless.
</li>
<li class="li ul-li list-star-li compact-li" data-line="961"><span data-line="961"></span>The type <span data-line="961"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">T</code><span data-line="961"></span> is a struct containing one member for each
directionless parameter of the hit action to be added.  The member
names must match the hit action parameter names, and their types
must be the same as the corresponding hit action parameters.
</li></ul>

<p class="p noindent" data-line="966"><span data-line="966"></span>The new entry will have the same key field values that were
searched for in the table when the miss occurred, which caused the
table<span data-line="968"></span>&#39;<span data-line="968"></span>s default action to be executed.  The action will be the one
named by the string that is the file of the parameter action<span data-line="969"></span>_<span data-line="969"></span>name.
</p>
<p class="p indent" data-line="971"><span data-line="971"></span>If the attempt to add a table entry succeeds, the return value is
<span data-line="972"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt"><span style="color:blue;font-weight:bold">true</span></code><span data-line="972"></span>, otherwise <span data-line="972"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt"><span style="color:blue;font-weight:bold">false</span></code><span data-line="972"></span>.
</p><h3 id="sec-idle-timeout" class="h2" data-line="975" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="975"></span><span class="heading-before"><span class="heading-label">8.2</span>.&#8194;</span><span data-line="975"></span>Table entry timeout notification</h3>
<p class="p noindent" data-line="977"><span data-line="977"></span>PNA uses the <span data-line="977"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_idle_timeout</code><span data-line="977"></span> to enable a table implementation send
notifications from the PNA device when a configurable time has passed
since an entry was last matched. The property may take one of two
values<span data-line="980"></span> <span data-line="980"></span>&#8211;<span data-line="980"></span> <span data-line="980"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NO_TIMEOUT</code><span data-line="980"></span>, and <span data-line="980"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NOTIFY_CONTROL</code><span data-line="980"></span>. <span data-line="980"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NO_TIMEOUT</code><span data-line="980"></span> disables
idle timeout support for the table and it is the default value when
the property is not present. <span data-line="982"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">NOTIFY_CONTROL</code><span data-line="982"></span> enables the
notification. A PNA implementation will then generate an API for the
control plane to set time-to-live (TTL) values for table entries and
if at any time during its lifetime, the table entry is not <span data-line="985"></span>&#8220;hit&#8221;<span data-line="985"></span> (<span data-line="985"></span>i.e.<span data-line="985"></span>
not selected by any packet lookup) for a lapse of time greater or
equal to its TTL, the device should generate a notification to the
control plane. The rate and mode of how the notifications are
generated and delivered to the control plane are subject to
configuration parameters specified by the control plane API.
</p>
<p class="p indent" data-line="992"><span data-line="992"></span>Example:
</p>
<div class="p4example" data-line="994" style="padding:6pt;margin-top:6pt;margin-bottom:6pt;border:solid;background-color:#ffffdd;border-width:0.5pt">
<div class="p4exampleblock" data-line="995">
<pre class="para-block pre-fenced pre-fenced4 language-p4 lang-p4 p4 colorized" data-line="996" data-line-first="997" style="display:block;font-family:monospace;font-size:10pt"><code data-line="997"><span style="color:teal;font-weight:bold">enum</span> PNA_IdleTimeout_t {
  NO_TIMEOUT,
  NOTIFY_CONTROL
}

<span style="color:blue;font-weight:bold">table</span> t {
  <span style="color:blue;font-weight:bold">action</span> a1 () { ... }
  <span style="color:blue;font-weight:bold">action</span> a2 () { ... }
  key = { hdr.f1: exact; }
  actions = { a1; a2; }
  default_action = a2;
  pna_idle_timeout = PNA_IdleTimeout_t.NOTIFY_CONTROL;
}</code></pre></div></div>
<p class="p noindent" data-line="1010"><span data-line="1010"></span>Restrictions on the TTL values and notifications:
</p>
<ul class="ul list-dash loose" data-line="1012">
<li class="li ul-li list-dash-li loose-li" data-line="1012">
<p data-line="1012"><span data-line="1012"></span>It is likely that any hardware implementation will have a limited
number of bits to represent the values, and, since the values are
programmed at runtime, it is the responsibility of the runtime
(P4Runtime or other controller software) to guarantee that the TTL
values can be represented in the device. This can be done by scaling
the values to the number of bits available on the platform, ensuring
that the range of values between different entries are
representable. A PNA implementation should only enable the
programming of such tables, and return an error if the device does
not support the idle timeout at all.
</p></li>
<li class="li ul-li list-dash-li loose-li" data-line="1023">
<p data-line="1023"><span data-line="1023"></span>If no value is programmed for a table entry, even though the table
has enabled the idle timeout property, the entry will not generate a
notification.
</p></li>
<li class="li ul-li list-dash-li loose-li" data-line="1027">
<p data-line="1027"><span data-line="1027"></span>PNA does not require a timeout value for a default action entry. The
reason for not making this mandatory in the specification is that
tthe default action may not have an explicit table entry to
represent it, and also there are no known compelling use cases for a
controller knowing when no misses have occurred for a particular
table for a long time. The default action entry will not be aged
out.
</p></li>
<li class="li ul-li list-dash-li loose-li" data-line="1035">
<p data-line="1035"><span data-line="1035"></span>Currently, tables implemented using ActionSelectors and
ActionProfiles do not support the <span data-line="1036"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna_idle_timeout</code><span data-line="1036"></span> property.
Future versions of the specification may remove this restriction.
</p></li></ul>
<h2 id="sec-timestamps" class="h1" data-line="1039" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1039"></span><span class="heading-before"><span class="heading-label">9</span>.&#8194;</span><span data-line="1039"></span>Timestamps</h2><h2 id="sec-atomicity-of-control-plane-api-operations" class="h1" data-line="1042" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1042"></span><span class="heading-before"><span class="heading-label">10</span>.&#8194;</span><span data-line="1042"></span>Atomicity of control plane API operations</h2><h2 id="sec-appendix--open-issues" class="h1" data-line="1044" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1044"></span><span class="heading-before"><span class="heading-label">A</span>.&#8194;</span><span data-line="1044"></span>Appendix: Open Issues</h2><h2 id="appendix-rationale" class="h1" data-line="1046" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1046"></span><span class="heading-before"><span class="heading-label">B</span>.&#8194;</span><span data-line="1046"></span>Appendix: Rationale for design</h2><h3 id="sec-why-a-common-pipeline-instead-of-separate-pipelines-for-each-direction" class="h2" data-line="1048" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1048"></span><span class="heading-before"><span class="heading-label">B.1</span>.&#8194;</span><span data-line="1048"></span>Why a common pipeline, instead of separate pipelines for each direction?</h3>
<div class="tbd" data-line="1050" style="color:red">
<div class="tbdblock" data-line="1051">
<p class="p noindent" data-line="1052"><span data-line="1052"></span>TBD: Andy can write this one.  Basic reasons are summarized in
existing slides.</p></div></div><h3 id="sec-why-separate-programmable-pre-blocks-for-pre-decryption-packet-processing" class="h2" data-line="1055" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1055"></span><span class="heading-before"><span class="heading-label">B.2</span>.&#8194;</span><span data-line="1055"></span>Why separate programmable pre blocks for pre-decryption packet processing?</h3>
<div class="tbd" data-line="1057" style="color:red">
<div class="tbdblock" data-line="1058">
<p class="p noindent" data-line="1059"><span data-line="1059"></span>TBD: Andy can write this one.  Basic reasons are summarized in
existing slides.</p></div></div><h3 id="appendix-reparsing" class="h2" data-line="1062" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1062"></span><span class="heading-before"><span class="heading-label">B.3</span>.&#8194;</span><span data-line="1062"></span>Is it inefficient to have the <span data-line="1062"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainParser</code><span data-line="1062"></span> redo work?</h3>
<p class="p noindent" data-line="1064"><span data-line="1064"></span>If the only changes made by the inline extern in the network-to-host
direction were to decrypt parts of the packet that were previously
encrypted, but everything before the first decrypted byte remained
exactly the same, then it seems like it is a waste of effort that the
main parser starts parsing the packet over again from the beginning.
</p>
<p class="p indent" data-line="1070"><span data-line="1070"></span>It is true that an IPsec decryption inline extern is unlikely to
change an Ethernet header at the beginning of the packet, but it does
seem likely that it could make the following kinds of changes to parts
of the packet before the first decrypted byte:
</p>
<ul class="ul list-dash compact" data-line="1075">
<li class="li ul-li list-dash-li compact-li" data-line="1075"><span data-line="1075"></span>Remove headers: If the received packet was IPsec tunnel mode, it
might be useful if the inline extern removes the outer IP header,
since it was added to the packet at the point of IPsec encryption.
The software sending the packet (before IPsec encryption occurred)
did not create that header, and the corresponding layer of software
receiving the decrypted packet does not want to see such
IPsec-specific headers.
</li>
<li class="li ul-li list-dash-li compact-li" data-line="1082"><span data-line="1082"></span>Modify headers: If the received packet was IPsec transport mode, it
might be useful if the IP header whose protocol was equal to the
standard numbers for AH or ESP was changed to be the next header
after the AH and ESP headers are removed by the inline extern.
Again, what an IPsec decryption block does might be useful to make
similar to what the IPsec layer of software does in a software IP
stack. The layer of software processing the decrypted packet should
see what the last layer of software sent before it was encrypted.
</li></ul>

<p class="p noindent" data-line="1091"><span data-line="1091"></span>If any or all of the above are true of the inline extern block<span data-line="1091"></span>&#39;<span data-line="1091"></span>s
changes to the packet, then it seems that the only way you could save
the main parser some work is to somehow encode the results of the pre
parser, and also undo those results for any headers that were modified
in the inline extern. Then you would also need the main parser to be
able to start from one of multiple possible states in the parser state
machine, and continue from there.
</p>
<p class="p indent" data-line="1099"><span data-line="1099"></span>That is all possible to do, but it seems like an awkward thing to
expose to a P4 developer, e.g. should we require them to write a main
parser that has a start state that immediately branches one of 7 ways
based upon some intermediate state the the pre parser reached, as
modified by the inline extern if it modified or removed some of those
headers?
</p>
<p class="p indent" data-line="1106"><span data-line="1106"></span>A NIC implementation might do such things, and it seems likely an
implementation might use some of the techniques mentioned in the
previous paragraph, but hidden from the P4 developer. The proposed PNA
design should not prevent this, if an implementer is willing to go to
that effort.
</p><h2 id="appendix-packet-path-figures" class="h1" data-line="1112" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1112"></span><span class="heading-before"><span class="heading-label">C</span>.&#8194;</span><span data-line="1112"></span>Appendix: Packet path figures</h2><h3 id="sec-network-to-host" class="h2" data-line="1114" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1114"></span><span class="heading-before"><span class="heading-label">C.1</span>.&#8194;</span><span data-line="1114"></span>Network to host</h3>
<figure id="fig-path-net-to-host" class="figure floating align-center float" data-line="1116" style="text-align:center;float-env:figure;float-name:Figure;page-align:forcehere">
<p class="p noindent" data-line="1117"><span data-line="1117"></span><img src="" alt="path-net-to-host" data-path="figs/path-net-to-host.png" data-linkid="path-net-to-host" style="width:100%"><span data-line="1117"></span>
</p>
<hr  class="figureline madoko" data-line="1118" style="display:block">

<div class="p noindent" data-line="1119"><span data-line="1119"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">4</span>.</strong>&#160;</span><span class="caption-text">Network to host packet path</span></fig-caption></div></figure>
<p class="p noindent" data-line="1121"><span data-line="1121"></span>See Figure<span data-line="1121"></span>&nbsp;<a href="#fig-path-net-to-host" title="Network to host packet path" class="localref" style="target-element:figure"><span class="figure-label">4</span></a><span data-line="1121"></span>. If decryption is desired, the
net-to-host inline extern performs it. If no decryption is required,
the net-to-host inline extern outputs the same packet payload that it
received, i.e. it is a no-op in the path.
</p><h3 id="sec-network-to-host-with-mirror-copy-to-different-host" class="h2" data-line="1126" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1126"></span><span class="heading-before"><span class="heading-label">C.2</span>.&#8194;</span><span data-line="1126"></span>Network to host with mirror copy to different host</h3>
<figure id="fig-path-net-to-host-with-mirror-copy-to-second-host" class="figure floating align-center float" data-line="1128" style="text-align:center;float-env:figure;float-name:Figure;page-align:forcehere">
<p class="p noindent" data-line="1129"><span data-line="1129"></span><img src="" alt="path-net-to-host-with-mirror-copy-to-second-host" data-path="figs/path-net-to-host-with-mirror-copy-to-second-host.png" data-linkid="path-net-to-host-with-mirror-copy-to-second-host" style="width:100%"><span data-line="1129"></span>
</p>
<hr  class="figureline madoko" data-line="1130" style="display:block">

<div class="p noindent" data-line="1131"><span data-line="1131"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">5</span>.</strong>&#160;</span><span class="caption-text">Network to host packet path, with mirror copy to second host</span></fig-caption></div></figure>
<p class="p noindent" data-line="1133"><span data-line="1133"></span>See Figure<span data-line="1133"></span>&nbsp;<a href="#fig-path-net-to-host-with-mirror-copy-to-second-host" title="Network to host packet path, with mirror copy to second host" class="localref" style="target-element:figure"><span class="figure-label">5</span></a><span data-line="1133"></span>.
This is similar to the network to host path, except that the
<span data-line="1135"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="1135"></span> code directs that the packet should be mirrored to a
second host, e.g. an inside-the-NIC CPU complex used for exception
packets. Logically, the copy occurs after the main deparser.
</p>
<p class="p indent" data-line="1139"><span data-line="1139"></span>One possibility for writing P4 code to do this is by having the
<span data-line="1140"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainDeparser</code><span data-line="1140"></span> optionally invoke a mirror extern, which could provide
an extra header to include before the mirrored copy.
</p><h3 id="sec-host-to-network" class="h2" data-line="1143" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1143"></span><span class="heading-before"><span class="heading-label">C.3</span>.&#8194;</span><span data-line="1143"></span>Host to network</h3>
<figure id="fig-path-host-to-net" class="figure floating align-center float" data-line="1145" style="text-align:center;float-env:figure;float-name:Figure;page-align:forcehere">
<p class="p noindent" data-line="1146"><span data-line="1146"></span><img src="" alt="path-host-to-net" data-path="figs/path-host-to-net.png" data-linkid="path-host-to-net" style="width:100%"><span data-line="1146"></span>
</p>
<hr  class="figureline madoko" data-line="1147" style="display:block">

<div class="p noindent" data-line="1148"><span data-line="1148"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">6</span>.</strong>&#160;</span><span class="caption-text">Host to network packet path</span></fig-caption></div></figure>
<p class="p noindent" data-line="1150"><span data-line="1150"></span>See Figure<span data-line="1150"></span>&nbsp;<a href="#fig-path-host-to-net" title="Host to network packet path" class="localref" style="target-element:figure"><span class="figure-label">6</span></a><span data-line="1150"></span>. If encryption is desired, the
host-to-net inline extern performs it. If no encryption is required,
the host-to-net inline extern outputs the same packet payload that it
received, i.e. it is a no-op in the path.
</p><h3 id="sec-host-to-network-with-mirror-copy-to-a-different-host" class="h2" data-line="1155" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1155"></span><span class="heading-before"><span class="heading-label">C.4</span>.&#8194;</span><span data-line="1155"></span>Host to network with mirror copy to a different host</h3>
<figure id="fig-path-host-to-net-with-mirror-copy-to-different-host" class="figure floating align-center float" data-line="1157" style="text-align:center;float-env:figure;float-name:Figure;page-align:forcehere">
<p class="p noindent" data-line="1158"><span data-line="1158"></span><img src="" alt="path-host-to-net-with-mirror-copy-to-different-host" data-path="figs/path-host-to-net-with-mirror-copy-to-different-host.png" data-linkid="path-host-to-net-with-mirror-copy-to-different-host" style="width:100%"><span data-line="1158"></span>
</p>
<hr  class="figureline madoko" data-line="1159" style="display:block">

<div class="p noindent" data-line="1160"><span data-line="1160"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">7</span>.</strong>&#160;</span><span class="caption-text">Host to network packet path, with mirror copy to a different host</span></fig-caption></div></figure>
<p class="p noindent" data-line="1162"><span data-line="1162"></span>See Figure<span data-line="1162"></span>&nbsp;<a href="#fig-path-host-to-net-with-mirror-copy-to-different-host" title="Host to network packet path, with mirror copy to a different host" class="localref" style="target-element:figure"><span class="figure-label">7</span></a><span data-line="1162"></span>.
This is similar to the host to network path, except that the
<span data-line="1164"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="1164"></span> code directs that the packet should be mirrored to a
host, e.g. an inside-the-NIC CPU complex used for exception packets.
Logically, the copy occurs after the main deparser.
</p>
<p class="p indent" data-line="1168"><span data-line="1168"></span>One possibility for writing P4 code to do this is by having the
<span data-line="1169"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainDeparser</code><span data-line="1169"></span> optionally invoke a mirror or mirror extern, which
could provide an extra header to include before the mirrored copy.
</p><h3 id="sec-host-to-host" class="h2" data-line="1172" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1172"></span><span class="heading-before"><span class="heading-label">C.5</span>.&#8194;</span><span data-line="1172"></span>Host to host</h3>
<figure id="fig-path-host-to-host" class="figure floating align-center float" data-line="1174" style="text-align:center;float-env:figure;float-name:Figure;page-align:forcehere">
<p class="p noindent" data-line="1175"><span data-line="1175"></span><img src="" alt="path-host-to-host" data-path="figs/path-host-to-host.png" data-linkid="path-host-to-host" style="width:100%"><span data-line="1175"></span>
</p>
<hr  class="figureline madoko" data-line="1176" style="display:block">

<div class="p noindent" data-line="1177"><span data-line="1177"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">8</span>.</strong>&#160;</span><span class="caption-text">Host to host packet path</span></fig-caption></div></figure>
<p class="p noindent" data-line="1179"><span data-line="1179"></span>See Figure<span data-line="1179"></span>&nbsp;<a href="#fig-path-host-to-host" title="Host to host packet path" class="localref" style="target-element:figure"><span class="figure-label">8</span></a><span data-line="1179"></span>. This path may more often be
called the VM to VM path.
</p>
<p class="p indent" data-line="1182"><span data-line="1182"></span>The host-to-net inline extern may be no-op or perform encryption, as
directed by the P4 code in the <span data-line="1183"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">MainControl</code><span data-line="1183"></span>. The net-to-host inline
extern may be no-op or perform decryption, as directed by the P4 code
in the <span data-line="1185"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">PreControl</code><span data-line="1185"></span>.
</p><h3 id="sec-port-to-port" class="h2" data-line="1187" data-heading-depth="2" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1187"></span><span class="heading-before"><span class="heading-label">C.6</span>.&#8194;</span><span data-line="1187"></span>Port to port</h3>
<figure id="fig-path-port-to-port-host-loopback" class="figure floating align-center float" data-line="1189" style="text-align:center;float-env:figure;float-name:Figure;page-align:forcehere">
<p class="p noindent" data-line="1190"><span data-line="1190"></span><img src="" alt="path-port-to-port-host-loopback" data-path="figs/path-port-to-port-host-loopback.png" data-linkid="path-port-to-port-host-loopback" style="width:100%"><span data-line="1190"></span>
</p>
<hr  class="figureline madoko" data-line="1191" style="display:block">

<div class="p noindent" data-line="1192"><span data-line="1192"></span><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure&#160;<span class="figure-label">9</span>.</strong>&#160;</span><span class="caption-text">Port to port packet path</span></fig-caption></div></figure>
<p class="p noindent" data-line="1194"><span data-line="1194"></span>See Figure<span data-line="1194"></span>&nbsp;<a href="#fig-path-port-to-port-host-loopback" title="Port to port packet path" class="localref" style="target-element:figure"><span class="figure-label">9</span></a><span data-line="1194"></span>. This path is shown
going through the memory of one of the hosts. The host could be a CPU
core complex within the NIC device itself, with its own memory, or it
could be a host CPU complex and its DRAM.
</p><h2 id="appendix-packet-ordering" class="h1" data-line="1199" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1199"></span><span class="heading-before"><span class="heading-label">D</span>.&#8194;</span><span data-line="1199"></span>Appendix: Packet ordering</h2><h2 id="appendix-revision-history" class="h1" data-line="1201" data-heading-depth="1" style="display:block;font-family:helvetica, sans-serif;font-weight:bold"><span data-line="1201"></span><span class="heading-before"><span class="heading-label">E</span>.&#8194;</span><span data-line="1201"></span>Appendix: Revision History</h2><table class="madoko block" data-line="1203">
<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-line="1203" data-row="0" data-col="1" style="text-align:center"></th><th class="thead tr-even col cell-border-left cell-line col-even" data-line="1203" data-row="0" data-col="2"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-line="1203" data-row="0" data-col="3"></th></tr>
<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-line="1204" data-row="1" data-col="1" style="font-weight:bold;text-align:center"><span data-line="1204"></span> Release </th><th class="col cell-border-left thead tr-odd tr-last tr-first col-even" data-line="1204" data-row="1" data-col="2" style="font-weight:bold"><span data-line="1204"></span> Release Date </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-odd col-last" data-line="1204" data-row="1" data-col="3" style="font-weight:bold"><span data-line="1204"></span> Summary of Changes </th></tr></thead>
<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1" style="text-align:center"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-row="0" data-col="2"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-row="0" data-col="3"></td></tr>
<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-line="1206" data-row="1" data-col="1" style="text-align:center"><span data-line="1206"></span> 0.1 </td><td class="tbody tr-odd tr-first col cell-border-left col-even" data-line="1206" data-row="1" data-col="2"><span data-line="1206"></span> November 5, 2020 </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-odd col-last" data-line="1206" data-row="1" data-col="3"><span data-line="1206"></span> Skeleton specification. </td></tr>
<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-line="1207" data-row="2" data-col="1" style="text-align:center"><span data-line="1207"></span> 0.5 </td><td class="tbody tr-even tr-last col cell-border-left col-even" data-line="1207" data-row="2" data-col="2"><span data-line="1207"></span> May 15, 2021 </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-odd col-last" data-line="1207" data-row="2" data-col="3"><span data-line="1207"></span> Initial draft. </td></tr>
<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-line="1208" data-row="2" data-col="1" style="text-align:center"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-line="1208" data-row="2" data-col="2"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-odd col-last" data-line="1208" data-row="2" data-col="3"></td></tr></tbody></table><span data-line=""></span>
<div class="footnotes madoko">
<hr >

<div id="fn-pnaportability" class="footnote" data-line="183" style="line-adjust:0">
<p class="p noindent" data-line="183"><span data-line="183"></span><span class="footnote-before"><sup><span class="footnote-label">1</span>.</sup></span><span data-line="183"></span>Of course, given the tight hardware resource
constraints on NIC devices, there is no promise that a given P4
program that compiles on one device will also compile on another
device. However, it should at least be the case that those P4
programs that are able to compile on multiple NIC devices should
process packets as described in this document.
<span data-line="189"></span><span data-line="189"></span><a href="#back-fn-pnaportability" class="footnote-backref localref">&#8617;</a></p></div>
<div id="fn-pnaexampleprograms" class="footnote" data-line="378" style="line-adjust:0">
<p class="p noindent" data-line="378"><span data-line="378"></span><span class="footnote-before"><sup><span class="footnote-label">2</span>.</sup></span><span data-line="378"></span><a href="https://github.com/p4lang/pna" class="texturl monospace">https://&#8203;github.&#8203;com/&#8203;p4lang/&#8203;pna</a><span data-line="378"></span>
in directory <span data-line="379"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">examples</code><span data-line="379"></span>.  Direct link:
<span data-line="380"></span><a href="https://github.com/p4lang/pna/tree/master/examples" class="texturl monospace">https://&#8203;github.&#8203;com/&#8203;p4lang/&#8203;pna/&#8203;tree/&#8203;master/&#8203;examples</a><span data-line="380"></span>
<span data-line="381"></span><span data-line="381"></span><a href="#back-fn-pnaexampleprograms" class="footnote-backref localref">&#8617;</a></p></div>
<div id="fn-pnap4targetspecific" class="footnote" data-line="462" style="line-adjust:0">
<p class="p noindent" data-line="462"><span data-line="462"></span><span class="footnote-before"><sup><span class="footnote-label">3</span>.</sup></span><span data-line="462"></span>It is expected that <span data-line="462"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna.p4</code><span data-line="462"></span> include files for
different targets will be nearly identical to each
other.  Besides the possibility of differing bit widths for these
PNA types, the only expected differences between <span data-line="465"></span><code class="code code1 language-p4 lang-p4 p4 colorized" style="font-family:monospace;font-size:10pt">pna.p4</code><span data-line="465"></span> files
for different targets would be annotations on externs, etc. that
the P4 compiler for that target needs to do its job.
<span data-line="468"></span><span data-line="468"></span><a href="#back-fn-pnap4targetspecific" class="footnote-backref localref">&#8617;</a></p></div>
<div id="fn-p4runtimeapi" class="footnote" data-line="477" style="line-adjust:0">
<p class="p noindent" data-line="477"><span data-line="477"></span><span class="footnote-before"><sup><span class="footnote-label">4</span>.</sup></span><span data-line="477"></span>The P4Runtime Specification can be found here:
<span data-line="478"></span><a href="https://p4.org/specs" class="texturl monospace">https://&#8203;p4.&#8203;org/&#8203;specs</a><span data-line="478"></span>
<span data-line="479"></span><span data-line="479"></span><a href="#back-fn-p4runtimeapi" class="footnote-backref localref">&#8617;</a></p></div></div></div>
</body>

</html>
